![Netty权威指南](https://wfqqreader-1252317822.image.myqcloud.com/cover/711/47378711/b_47378711.jpg)
2.3.4 NIO客户端序列图
NIO客户端创建序列图如图2-11所示。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/53_1.jpg?sign=1738852362-pKwhVByPX1BFh2rUgvChQqjNOSOqZ4So-0-ed86955333d695b13d93d4232142776f)
图2-11 NIO客户端创建序列图
步骤一:打开SocketChannel,绑定客户端本地地址(可选,默认系统会随机分配一个可用的本地地址),示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_1.jpg?sign=1738852362-OVYwPtSgoIITvFEy4nzy70Y74OkMYT3b-0-0f76d2a00ada86f0a1fcf8b5848370bc)
步骤二:设置SocketChannel为非阻塞模式,同时设置客户端连接的TCP参数,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_2.jpg?sign=1738852362-POW4DzjcC1Ggac7egfZ3wwjoBXJVRmgK-0-781d863691438bd98f5fca7080d457f9)
步骤三:异步连接服务端,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_3.jpg?sign=1738852362-VYTXKD8JLLQNIJgZNilHt1o5OJSgYjGM-0-402bf734a88a273951f63498b1c99800)
步骤四:判断是否连接成功,如果连接成功,则直接注册读状态位到多路复用器中,如果当前没有连接成功(异步连接,返回false,说明客户端已经发送sync包,服务端没有返回ack包,物理链路还没有建立),示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_4.jpg?sign=1738852362-k3bHqO0mi4LVkL1xD5VpY7ab2idXan1f-0-3c951832cd9256c4aebb9c0f87731cef)
步骤五:向Reactor线程的多路复用器注册OP_CONNECT状态位,监听服务端的TCP ACK应答,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_5.jpg?sign=1738852362-ti02RBXbCw9YccKLuyKSOaL6KXgy1Iis-0-3bf9f9b86c9f3ecb1f3b6342a711f89f)
步骤六:创建Reactor线程,创建多路复用器并启动线程,代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_6.jpg?sign=1738852362-ht4wvYnxO8NowmIVBaIjaUkgWlsCmtTZ-0-42de5ec069f7d6edfb17c2ec2acb9470)
步骤七:多路复用器在线程run方法的无限循环体内轮询准备就绪的Key,代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_7.jpg?sign=1738852362-GioqRsZamE8ojaCWAab5UkLsRNkMrMDN-0-614cbbeb584a0f07f4e31d2202e4583f)
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_1.jpg?sign=1738852362-k0pCqi2za2f3ZtQZFC17bEuSyr1Kxfbs-0-532f55caa97901260d5649b1789ee23b)
步骤八:接收connect事件进行处理,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_2.jpg?sign=1738852362-tbTHMXwNwwCJCCNxDBnJrTyflsKqhLYP-0-19544bcdc90415cfda260b9f35ddf4de)
步骤九:判断连接结果,如果连接成功,注册读事件到多路复用器,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_3.jpg?sign=1738852362-C1gIsrhcfMt1xcXBYzG4WfV1eOiM7oHP-0-27f2f7517d2784c1821c7f39db5676a1)
步骤十:注册读事件到多路复用器,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_4.jpg?sign=1738852362-pkwrtT4GXtZJnfvYBXoPjiHhsrDJbUkZ-0-6f2d286faca3bdab60b1d7cc246bb93c)
步骤十一:异步读客户端请求消息到缓冲区,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_5.jpg?sign=1738852362-M4Rw6ULSCOynyjcx23iX5EOcy2993vk9-0-6717f567ce06bf96f35c55304c86c655)
步骤十二:对ByteBuffer进行编解码,如果有半包消息接收缓冲区Reset,继续读取后续的报文,将解码成功的消息封装成Task,投递到业务线程池中,进行业务逻辑编排,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_6.jpg?sign=1738852362-XovxkQviHYs4LO62ZZkb5kF7dX8dtqmm-0-e78a78b9c2a94c495682d5c1768c6f34)
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/56_1.jpg?sign=1738852362-e3rzocwmrKidopCbWV5RdxjHQiChiEYK-0-75ccf5f7f326de0848c6e38096fda45d)
步骤十三:将POJO对象encode成ByteBuffer,调用SocketChannel的异步write接口,将消息异步发送给客户端,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/56_2.jpg?sign=1738852362-R2D5LbtKwaHyxMxis6zKXkWxdb8DU4j1-0-4a7c48704348a10999c32a565be34fe5)
通过序列图和关键代码的解说,相信大家对创建NIO客户端程序已经有了一个初步的了解,下面就跟随着我们的脚步,继续看看如何使用NIO改造之前的时间服务器客户端TimeClient吧。