NIO客户端主要创建过程

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);
时间: 2024-10-07 22:25:57

NIO客户端主要创建过程的相关文章

netty 5 alph1源码分析(服务端创建过程)

参照<Netty系列之Netty 服务端创建>,研究了netty的服务端创建过程.至于netty的优势,可以参照网络其他文章.<Netty系列之Netty 服务端创建>是 李林锋撰写的netty源码分析的一篇好文,绝对是技术干货.但抛开技术来说,也存在一些瑕疵. 缺点如下 代码衔接不连贯,上下不连贯. 代码片段是截图,对阅读代理不便(可能和阅读习惯有关) 本篇主要内容,参照<Netty系列之Netty 服务端创建>,梳理出自己喜欢的阅读风格. 1.整体逻辑图 整体将服务

一个ActiveX control的创建过程

创建 根据这篇文章的介绍:http://www.cnblogs.com/time-is-life/p/6354152.html 来创建,里面包含了创建的基本过程以及属性事件方法的使用. 使用: 参考文章中建议使用ActiveX Control Pad,这个工具确实很好用,能够自动生成带有Active x控件的网页,而且可以直接设计和配置参数.但是这个工具只在老的32位系统可以使用,我试了Windows server 2008 32位系统,装不上,其他的64位系统也装不上.最后在一台XP的机器上装

设置 Oracle,Sqlplus,Linux 设置为UTF8 专治中文乱码 ,查看表的创建过程

[本文谢绝转载原文来自http://990487026.blog.51cto.com] 思想: 1,设置Linux字符集 为UTF8编码 2,设置Oracle字符集 为UTF8编码 3,设置sqlplus客户端环境 为UTF8编码 4,如果是在Windows使用CRT/Xshell远程工具,请设置软件编码为UTF8[略...] 1,先设置oracle为UTF8 [[email protected] ~]$ sqlplus /nolog SQL> conn /as sysdba; SQL> sh

【深入理解Java虚拟机】Java内存区域模型、对象创建过程、常见OOM

本文内容来源于<深入理解Java虚拟机>一书,非常推荐大家去看一下这本书.最近开始看这本书,打算再开一个相关系列,来总结一下这本书中的重要知识点.呃呃呃,说好的那个图片请求框架呢~  不要急哈,因为这个请求框架设计的内容还是比较广的,目前业余时间正在编写当中,弄好了之后就会放上来.在完成之前,咱还是先来学习一下其他知识. 1.内存模型 java虚拟机在执行java程序的过程中会把它说管理的内存划分为若干个不同的数据区域,如下图所示: 图片来源于网络 (1)程序计数器(Program Count

Netty源码分析 (六)----- 客户端接入accept过程

通读本文,你会了解到1.netty如何接受新的请求2.netty如何给新请求分配reactor线程3.netty如何给每个新连接增加ChannelHandler netty中的reactor线程 netty中最核心的东西莫过于两种类型的reactor线程,可以看作netty中两种类型的发动机,驱动着netty整个框架的运转 一种类型的reactor线程是boos线程组,专门用来接受新的连接,然后封装成channel对象扔给worker线程组:还有一种类型的reactor线程是worker线程组,

Android4.4 Framework分析——Activity窗口的创建过程(一)

学习android的窗口模块一周多了,感觉自己对这个模块的理解还是比较模糊,先把get的知识点记录一下. 下图是学习过程记录的activity窗口启动过程序列图,没有或者没办法完整的描绘出来,整个过程比较复杂: 整个学习过程中是参照老罗的android之旅博客和<深入理解android内核设计思想>一书来辅助的,非常感谢前辈. Activity的整体启动过程可查看Android4.4 framework分析--Launcher中启动应用程序(startActivity)的过程的序列图,本文关注

图解java对象的创建过程

前面几篇博文分别介绍了JAVA的Class文件格式.JVM的类加载机制和JVM的内存模型,这里就索性把java对象的创建过程一并说完,这样java对象的整个创建过程就基本上说明白了(当然你要有基础才能真正看明白).经常有人问我为什么这么喜欢钻研底层的东西,首先,因为我以前的做硬件的和嵌入式的,兴趣使然:其次,我个人感觉,如果不把上下打通,心里老是有一堵墙过不去,说白了,这是个人因素,与好坏无关(当然,经常有人说,懂底层原理是成为高手的必经之路). 现在来说一下我当初学习JVM的原因,在学习JAV

Android Context创建过程

    特定的资源或者类构成了Android应用程序的运行上下文环境 PackageManager, ClassLoader, Assert等等 Android应用程序窗口的运行上下文环境是通过ContextImpl类来描述的,即每一个Activity组件都关联有一个ContextImpl对象.ContextImpl类继承了Context类,它与Activity组件的关系如图 这个类图在设计模式里面就可以称为装饰模式 Activity组件以后就可以通过这个ContextImpl对象来执行一些具体

oracle link的创建过程

下面做一个测试,在测试中,创建数据库链接的库为XJ(WINDOWS 2003 ORACLE 10g 10.2.0.1),被链接的库为DMDB(LINUX AS5 ORACLE 10g 10.2.0.1 RAC)第一部分:如何创建dblinkdblink的创建有两种方式:1.在本地数据库tnsnames.ora文件中配置要访问的目标数据库信息create [public] database link test_link2connect to scott identified by tiger us