![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=1738823897-wUrSfMaG0o0zl8cBTFBFrq5bTkLog8Hf-0-b0f7aa9eec69815a11824d0f23ab01bd)
图2-11 NIO客户端创建序列图
步骤一:打开SocketChannel,绑定客户端本地地址(可选,默认系统会随机分配一个可用的本地地址),示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_1.jpg?sign=1738823897-Ui7Pv7x7m5eQJGDWP0QY7eNBAtoYe01u-0-e5de2bb8ba745b54d3765ec381a50109)
步骤二:设置SocketChannel为非阻塞模式,同时设置客户端连接的TCP参数,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_2.jpg?sign=1738823897-3gTzdISAUP6fyecyWcZdUUeo0kL9DSBb-0-33ed24bd5f89bfef1e689fe9ca54d218)
步骤三:异步连接服务端,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_3.jpg?sign=1738823897-xQ2HP0Vm3jXKkdFmgsEIgYVCLpjkEl0n-0-be865fbddfacc83271a4a3fdfe1f6277)
步骤四:判断是否连接成功,如果连接成功,则直接注册读状态位到多路复用器中,如果当前没有连接成功(异步连接,返回false,说明客户端已经发送sync包,服务端没有返回ack包,物理链路还没有建立),示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_4.jpg?sign=1738823897-js74pM2k7grOHjqsvJaU8RP5braheulr-0-11d579e8eca00ec70633d320ddaf0d68)
步骤五:向Reactor线程的多路复用器注册OP_CONNECT状态位,监听服务端的TCP ACK应答,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_5.jpg?sign=1738823897-kQ1TfLfBxoKx3snHubkj4ciDmlW7t3Ep-0-44c4ad4df1dd2427557b4109ca6ccb7c)
步骤六:创建Reactor线程,创建多路复用器并启动线程,代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_6.jpg?sign=1738823897-OC0JwpazxqjWtHZS1EBzqUw6vdYZCoyC-0-937f934e5e4c5fd9a15422c365e8c3d7)
步骤七:多路复用器在线程run方法的无限循环体内轮询准备就绪的Key,代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_7.jpg?sign=1738823897-A1yBgBZ775rX7659vldLc279xRW2erJd-0-bb8c1025475f082c23063c025184b3dd)
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_1.jpg?sign=1738823897-L9uEIeVF2neVHpUmN86ZUx33j7l9Zb0u-0-1e10296d21fc3183cefd4b85a917aa51)
步骤八:接收connect事件进行处理,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_2.jpg?sign=1738823897-r1eUSla1nC1K7muCtQCl164bLbzo9wl1-0-caa785cae52742c2e1dfba649d3c497a)
步骤九:判断连接结果,如果连接成功,注册读事件到多路复用器,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_3.jpg?sign=1738823897-1GJ4aNxiIUwpw0vcPviGv5XgGQrC1RB6-0-5b5a6ae9e53c56f63e7502f2681352cf)
步骤十:注册读事件到多路复用器,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_4.jpg?sign=1738823897-Jlgu8i9O5yRg4tmzJo2zXalZYfHtsnYJ-0-bfbc33160d3d55673c8ad367058dcfa7)
步骤十一:异步读客户端请求消息到缓冲区,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_5.jpg?sign=1738823897-pVEOjAeVFpZg3cZxjAMrHF7si5N1wY7D-0-edd7918d0a4d7096e46e64b7bc97ed92)
步骤十二:对ByteBuffer进行编解码,如果有半包消息接收缓冲区Reset,继续读取后续的报文,将解码成功的消息封装成Task,投递到业务线程池中,进行业务逻辑编排,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_6.jpg?sign=1738823897-hZ6dm4gYBGWuDPuXVhQqdR4amOj6QQ4B-0-45d5ac498a3f7e35b867d43db13cf899)
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/56_1.jpg?sign=1738823897-jZoQfol77CKUMt5qUgC0AODTEeYgJIGO-0-bb6c48c7594484044e5a8890383a6539)
步骤十三:将POJO对象encode成ByteBuffer,调用SocketChannel的异步write接口,将消息异步发送给客户端,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/56_2.jpg?sign=1738823897-a2ZB88ZQpOSX5lsnHvTx7SEt7xTCtqke-0-567ef0ae56714bc57375b5d5f0c0739f)
通过序列图和关键代码的解说,相信大家对创建NIO客户端程序已经有了一个初步的了解,下面就跟随着我们的脚步,继续看看如何使用NIO改造之前的时间服务器客户端TimeClient吧。