NIO客户端主要创建过程:
 
步骤一:打开SocketChannel,绑定客户端本地地址(可选,默认系统会随机分配一个可用的本地地址),示例代码如下: 
 
SocketChannel clientChannel = SocketChannel.open(); 
 
步骤二:设置SocketChannel为非阻塞模式,同时设置客户端连接的TCP参数,示例代码如下:
 
ClientChannel.configureBlocking(false);
socket.setReuseAddress(true);
socket.setReceiveBufferSize(BUFFER_SIZE);
socket.setSendBufferSize(BUFFER_SIZE);
 
步骤三:异步连接服务端,示例代码如下:
 
boolean connected = clientChannel.connect(new InetSocketAddress(IP,port));
 
步骤四:判断是否连接成功,如果连接成功,则直接注册读状态为到多路复用器中,如果当前没有连接成功(异步连接,返回false,说明客户端已经发送sync包,服务端没有返回ack包,物理链路还没有建立),示例代码如下:
 
if(connected){
clientChannel.register(seletor,SelectionKey.OP_READ,ioHandler);
}else{
clientChannel.register(selector,Selection.OP_CONNECT,ioHandler);
}

步骤五:向Reactor线程的多路复用器注册OP_CONNET状态位,监听服务端的TCP ACK应答,示例代码如下:

 clientChannel.register(select, SelectionKey.OP_CONNECT,ioHandler);
 
步骤六:创建Reactor线程,创建多路复用器并启动线程,示例代码如下:
 
Selector selector = Selector.open();
New Thread(new ReactorTask()).start();

步骤七:多路复用器在线程run方法的无限循环体内轮询准备就绪的Key,示例代码如下:

int num = selector.select();
Set selectedKeys = selector.selectedKeys();
Iterator it = selectedKeys.iterator();
while(it.hasNext){
SelectionKey key = (SelectionKey)it.next();
//...deal with I/O event ...
}
 
步骤八:接收connect事件进行处理,示例代码如下:

if(key.isConnectable()){
//handlerConnect();
}

步骤九:判断连接成功,如果连接成功,注册读事件到多路复用器,示例代码如下:

if(channel.finishConnect()){
registerRead();
}
 
步骤十:注册读事件到多路复用器,示例代码如下:
 
clientChannel.register(selector,SelectionKey.OP_READ,ioHandler);

步骤十一:异步读客户端请求消息到缓冲区,示例代码如下:

int readNumber = channel.read(receivedBuffer);

步骤十二:对ByteBuffer进行编解码,如果有半包消息接收缓冲区Reset,继续读取后续的报文,将解码成功的消息封装成Task,投递到业务线程池中,进行业务逻辑编排,示例代码如下:

Object message = null;
whiel(buffer.hasRemain()){
byteBuffer.mark();
Object message = decode(byteBuffer);
if(message == null){
byteBuffer.reset();
break;
}
messageList.add(message);
}
if( !byteBuffer.hasRemain()){
byteBuffer.clear();
}else{
byteBuffer.compact();
}
if(messageList != null & !messageList.isEmpty()){
for(Object messageE : messageList){
handlerTask(messageE);
}
}

步骤十三:将POJO对象encode成ByteBuffer,调用SocketChannel的异步write接口,将消息异步发送给客户端。示例代码如下:

socketChannel.write(buffer);

最新文章

  1. mac eclipse 下安装subclipse
  2. Android Studio系列教程一--下载与安装
  3. 根据条件自定义 cxGrid 的单元格样式
  4. C++中new与delete问题学习
  5. Spark Streaming揭秘 Day16 数据清理机制
  6. hdoj 2602(背包)
  7. android 点击桌面图标,打开手机浏览器进入对应的站点
  8. Spark添加/更改集群节点需要修改的配置文件
  9. (IOS)N duplicate symbols for architecture i386
  10. Linux.根据进程名关键字杀进程
  11. node.js爬虫
  12. [转]在ASP.NET Core中使用百度在线编辑器UEditor
  13. DevExpress破解和消除弹出框问题
  14. Java 10 实战第 1 篇:局部变量类型推断
  15. Android动态添加Fragment
  16. ThreadPoolExecutor 源码阅读
  17. springmvc请求路径和请求参数的获取注解- @PathVariable和@RequestParam
  18. 【学习】Hall’s Marriage Theorem
  19. isinstance, type, issubclass
  20. Python下HttpHTTPClient和AsyncHTTPClient

热门文章

  1. field 属性操作
  2. kbmMemTable关于内存表的使用,以及各种三层框架的评价
  3. android adb 源码框架分析(1 系统)【转】
  4. fuse的mount机制-流程及参数
  5. bzoj1911 [Apio2010]特别行动队——斜率优化DP
  6. bzoj1038&&500AC!
  7. Javaweb中利用kaptcha生成验证码
  8. apache禁止使用IP访问的实现方法
  9. css里关于浏览器的前缀
  10. Educational Codeforces Round 21E selling souvenirs (dp)