高并发网络编程pdf(java高并发与网络编程实战)
socket高并发网络编程服务端有什么框架?
netty;
PayServer.java
package com.miri.pay.scoket;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PayServer implements Runnable
{
private static final Logger DLOG = LoggerFactory.getLogger(PayServer.class);
private final int port;
public PayServer(int port)
{
this.port = port;
}
/**
* 为ServerBootstrap绑定指定端口
*/
public void run()
{
// 用于接收发来的连接请求
final EventLoopGroup bossGroup = new NioEventLoopGroup();
// 用于处理boss接受并且注册给worker的连接中的信息
final EventLoopGroup workerGroup = new NioEventLoopGroup();
try
{
// 配置服务器
final ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup);
bootstrap.channel(NioServerSocketChannel.class);
bootstrap.option(ChannelOption.SO_BACKLOG, 128);
// 通过NoDelay禁用Nagle,使消息立即发出去,不用等待到一定的数据量才发出去
bootstrap.option(ChannelOption.TCP_NODELAY, true);
// 保持长连接状态
bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
// CustomChannelInitializer是一个特殊的handler,用于方便的配置用户自定义的handler实现
bootstrap.childHandler(new CustomChannelInitializer());
// 绑定并开始接受传入的连接
final ChannelFuture future = bootstrap.bind(this.port).sync();
if (future.isSuccess())
{
PayServer.DLOG.info("Start the socket server {} success", this.port);
}
else
{
PayServer.DLOG.info("Start the socket server {} failure,System exit!", this.port);
throw new RuntimeException("Socket服务端启动失败");
}
// 等待服务器套接字关闭
// 关闭服务器
future.channel().closeFuture().sync();
}
catch (final InterruptedException e)
{
PayServer.DLOG.error("Close the socket server exception occurs,System exit!", e);
throw new RuntimeException("关闭Socket服务端失败");
}
finally
{
// 关闭所有事件循环终止线程
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
/**
* 特殊的内部类
* p
* 是一个特殊的handler,用于方便的配置用户自定义的handler实现
* @author xulonghui
*/
static class CustomChannelInitializer extends ChannelInitializerSocketChannel
{
@Override
protected void initChannel(SocketChannel ch) throws Exception
{
final ChannelPipeline p = ch.pipeline();
p.addLast(new PayMessageEncoder());
p.addLast(new PayMessageDecoder());
p.addLast(new PayServerHandler());
}
}
}
PayMessageEncoder.java
package com.miri.pay.scoket;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import io.netty.util.CharsetUtil;
import com.miri.pay.model.CommonResponse;
import com.miri.pay.utils.JsonUtil;
/**
*消息编码器
* p
* 编码从服务端发送出的消息
*/
public class PayMessageEncoder extends MessageToByteEncoderCommonResponse
{
@Override
protected void encode(ChannelHandlerContext ctx, CommonResponse rsp, ByteBuf out) throws Exception
{
if (rsp != null)
{
final Object msgContent = rsp.getMsgContent();
// 消息ID,sequenceId和entityId三个加起来是12个长度
int msgLen = 12;
byte[] contentbs = new byte[] {};
if (msgContent != null)
{
final String content = JsonUtil.bean2json(msgContent);
contentbs = content.getBytes(CharsetUtil.UTF_8);
final int cl = contentbs.length;
msgLen += cl;
}
out.writeInt(msgLen);// 写入当前消息的总长度
out.writeInt(rsp.getMsgId());// 写入当前消息的消息ID
out.writeInt(rsp.getSequenceId());// 写入当前消息的SequenceId
out.writeInt(rsp.getEntityId());// 写入当前消息的EntityId
// 写入消息主体内容
if (contentbs.length 0)
{
out.writeBytes(contentbs);
}
}
}
}
PayMessageDecoder.java
package com.miri.pay.scoket;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.util.CharsetUtil;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.miri.pay.constants.Constants;
import com.miri.pay.model.CommonRequest;
import com.miri.pay.utils.ByteUtil;
/**
* 消息解码器
* p
* 解码从客户端请求的消息
*/
public class PayMessageDecoder extends ByteToMessageDecoder
{
private static final Logger DLOG = LoggerFactory.getLogger(PayMessageDecoder.class);
/**
* 表示头长度的字节数
*/
private static final int HEAD_LENGTH = 4;
/**
* 所有ID串所属的字节数
*/
private static final int ID_STR_LENGTH = 12;
/**
* 单个ID所属的字节数
*/
private static final int SINGLE_ID_LENGTH = 4;
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, ListObject out) throws Exception
{
int readable = in.readableBytes();
if (readable PayMessageDecoder.HEAD_LENGTH)
{
return;
}
in.markReaderIndex(); // 我们标记一下当前的readIndex的位置
final int dataLength = in.readInt(); // 读取传送过来的消息的长度。ByteBuf 的readInt()方法会让他的readIndex增加4
if (dataLength 0)
{
// 我们读到的消息体长度为0,这是不应该出现的情况,这里出现这情况,关闭连接。
ctx.close();
}
readable = in.readableBytes();
if (readable dataLength)
{
// 读到的消息体长度如果小于我们传送过来的消息长度,则resetReaderIndex. 这个配合markReaderIndex使用的。把readIndex重置到mark的地方
in.resetReaderIndex();
return;
}
final byte[] body = new byte[dataLength];
in.readBytes(body);
// 判断是否读取到内容
final int length = body.length;
if (length == 0)
{
return;// 若未读出任何内容,则忽略
}
out.add(this.byte2req(body));
}
/**
* 将读取到的byte数据转换为请求对象
* @param body
* @return
* @throws Exception
*/
private CommonRequest byte2req(byte[] body) throws Exception
{
final CommonRequest req = new CommonRequest(Constants.INVALID_MSGID);
final int length = body.length;
// 若内容数组的长度小于或等于12,则表示消息主体内容为空,直接返回一个无效的消息出去
if (length PayMessageDecoder.ID_STR_LENGTH)
{
PayMessageDecoder.DLOG
.info("The client sends the message length is: {}, is invalid message, directly returns a msgId = {} request entity",
length, Constants.INVALID_MSGID);
return req;
}
// 获取消息ID
final byte[] mbs = new byte[PayMessageDecoder.SINGLE_ID_LENGTH];
System.arraycopy(body, 0, mbs, 0, PayMessageDecoder.SINGLE_ID_LENGTH);
final int msgId = ByteUtil.byte4toint(mbs);
req.setMsgId(msgId);
// 获取sequenceId
final byte[] sbs = new byte[PayMessageDecoder.SINGLE_ID_LENGTH];
System.arraycopy(body, 4, sbs, 0, PayMessageDecoder.SINGLE_ID_LENGTH);
final int sequenceId = ByteUtil.byte4toint(sbs);
req.setSequenceId(sequenceId);
// 获取entityId
final byte[] ebs = new byte[PayMessageDecoder.SINGLE_ID_LENGTH];
System.arraycopy(body, 8, ebs, 0, PayMessageDecoder.SINGLE_ID_LENGTH);
final int entityId = ByteUtil.byte4toint(ebs);
req.setEntityId(entityId);
// 获取消息主体内容
if (length PayMessageDecoder.ID_STR_LENGTH)
{
final int contentLen = length - PayMessageDecoder.ID_STR_LENGTH;
final byte[] contentbs = new byte[contentLen];
System.arraycopy(body, 12, contentbs, 0, contentLen);
final String content = new String(contentbs, CharsetUtil.UTF_8);
req.setMsgContent(content);
}
return req;
}
}
PayServerHandler.java
package com.miri.pay.scoket;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.miri.pay.MessageQueue;
import com.miri.pay.model.CommonRequest;
import com.miri.pay.model.PendingBean;
/**
* Socket服务端处理器
*/
public class PayServerHandler extends ChannelInboundHandlerAdapter
{
private static final Logger DLOG = LoggerFactory.getLogger(PayServerHandler.class);
/**
* 外部订单号-频道
*/
public static final MapString, Channel CHANNELS = new HashMapString, Channel();
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
{
try
{
PayServerHandler.DLOG.info("Client send to msg is: {}", msg);
final CommonRequest request = (CommonRequest) msg;
final PendingBean bean = new PendingBean(ctx.channel(), request);
MessageQueue.offer(bean);
}
finally
{
ReferenceCountUtil.release(msg);
}
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception
{
ctx.flush();
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception
{
super.channelActive(ctx);
final Channel channel = ctx.channel();
PayServerHandler.DLOG.info("Client active form {}", channel.remoteAddress());
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception
{
super.channelInactive(ctx);
final Channel channel = ctx.channel();
PayServerHandler.DLOG.info("Client inactive form {}", channel.remoteAddress());
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
{
PayServerHandler.DLOG.error("System exception", cause);
ctx.close();
}
}
《UNIX网络编程卷1套接字联网API第3版》pdf下载在线阅读全文,求百度网盘云资源
《UNIX网络编程卷1套接字联网API第3版》百度网盘pdf最新全集下载:
链接:
?pwd=riwe 提取码:riwe
简介:UNIX网络编程卷1套接字联网API第3版全面深入地介绍了如何使用套接字API进行网络编程。全书不但介绍了基本编程内容,还涵盖了与套接字编程相关的高级主题,对于客户/服务器程序的各种设计方法也作了完整的探讨,最后还深入分析了流这种设备驱动机制。 ?
《Python网络编程基础》pdf下载在线阅读全文,求百度网盘云资源
《python网络编程基础》百度网盘pdf最新全集下载:
链接:
?pwd=c8d1 提取码:c8d1
简介:25年前,世界和现在是完全不同的。很少人能有机会和大洋彼岸的人谈话。寄一封信需要好几周的时间。收听外国的短波新闻广播除了需要专门的技术和耐心外,还要非常好的气候条件。而今天,收到来自韩国的E-mail、查看加利福尼亚的天气,以及阅读德国当天的头条新闻对我们来说都是很平常的事情,而且都可以在五分钟之内完成。压缩文件在互联网上的传输使得我们可以做很多事情,从管理投资账户到观看远房亲戚的照片。
尽管Internet已经有25年的历史了,但它还是处在幼年阶段。作为一种新技术,它还在逐渐成长。
我写这本书的原因是因为Internet是那么地让人兴奋。在过去的几年中,我们看到了整个行业的增长,而这些是以前没有的。同时互联网也是产生大量发明家的地方。
而且这也是我希望您从本书获得的,我希望这本书能成为您的实验手册--您为了使Internet更美好而进行发明创造的指南。 ?
《Android4.0网络编程详解》pdf下载在线阅读,求百度网盘云资源
《Android 4.0网络编程详解》(王家林)电子书网盘下载免费在线阅读
资源链接:
链接:
?提取码:6shy?? ?
书名:Android 4.0网络编程详解
作者:王家林
出版社:电子工业出版社
出版年份:2012-1
页数:374
内容简介:《Android 4.0网络编程详解》对Android 4.0网络编程中的XML形式,JSON操作,需要掌握的HTTP知识,数据下载/上传,Socket编程,浏览器开发,Android中软件界面设计新大陆——采用HTML设计软件界面,Android应用程序的生命周期等内容进行了深入的讲解。