![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=1734385946-PUJK97Q2kHEb8M6ZDXO2YYFK0XcqKvNe-0-a1862f7e0bf2f06c306249a4038a8fd5)
图2-11 NIO客户端创建序列图
步骤一:打开SocketChannel,绑定客户端本地地址(可选,默认系统会随机分配一个可用的本地地址),示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_1.jpg?sign=1734385946-PLIJwoLQ05QiAn61piv0k08gwBZsEzon-0-2417bdfcbb43e9c65b2fbb507cf149d0)
步骤二:设置SocketChannel为非阻塞模式,同时设置客户端连接的TCP参数,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_2.jpg?sign=1734385946-4WpdIxzdtrRCaQie5c9PQsR8IwlWruvi-0-270cf3ace70f12d554f63512cf33ef6f)
步骤三:异步连接服务端,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_3.jpg?sign=1734385946-S0RsMjY13jc43sV4epxX0m2nZBZKST6Z-0-941756063fa4a2af41cef74146a11f8f)
步骤四:判断是否连接成功,如果连接成功,则直接注册读状态位到多路复用器中,如果当前没有连接成功(异步连接,返回false,说明客户端已经发送sync包,服务端没有返回ack包,物理链路还没有建立),示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_4.jpg?sign=1734385946-vxoxuWPSGY45dmYJN5YF6hkXEXb06XEH-0-dc2e8abb788d3c4b27948d8ec3d20261)
步骤五:向Reactor线程的多路复用器注册OP_CONNECT状态位,监听服务端的TCP ACK应答,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_5.jpg?sign=1734385946-So0QLkpcZjVtMHtizkW71phSHeAuBMiV-0-ff69ffa6f930e7495b5b1d11aecaca5b)
步骤六:创建Reactor线程,创建多路复用器并启动线程,代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_6.jpg?sign=1734385946-xgJcvM4dUdlpv7UAREOnAmrRs4L77757-0-c2efdc7cb93e3efc8b43dec02912a92b)
步骤七:多路复用器在线程run方法的无限循环体内轮询准备就绪的Key,代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_7.jpg?sign=1734385946-8HwksNUlbhFnk2hR6bk0c32FX11lb7vk-0-99ecbc97d84573ff999a67ace63fd5aa)
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_1.jpg?sign=1734385946-koOOtqn9XuZlVwtJEIpIOjKfcs3MeH1d-0-b161b5d503211a02996e41411f875db2)
步骤八:接收connect事件进行处理,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_2.jpg?sign=1734385946-CfyqQIy04PWBC8PtwuN4iiEmMYL9u0OY-0-d5e94d5391dccaaf808d78f1ec77e712)
步骤九:判断连接结果,如果连接成功,注册读事件到多路复用器,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_3.jpg?sign=1734385946-v9dBlFkCFi9bWiKpIfFzYVaW6wBVvAW7-0-ce51f5a6d5f4706ef34537902a9bd089)
步骤十:注册读事件到多路复用器,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_4.jpg?sign=1734385946-241bAwVJ3b8jHgoEZnotwG4kT0ubJ9oq-0-102e7da7fa92a8b7dba3db1e86cb8587)
步骤十一:异步读客户端请求消息到缓冲区,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_5.jpg?sign=1734385946-ZbvhZIrA2Xi3TRpHWuVDQXKLHhSGNxga-0-b8ebdb752cc7ddaeaa0155dc2ccdcb90)
步骤十二:对ByteBuffer进行编解码,如果有半包消息接收缓冲区Reset,继续读取后续的报文,将解码成功的消息封装成Task,投递到业务线程池中,进行业务逻辑编排,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_6.jpg?sign=1734385946-79L79KEfNYioTzwCxrDF4slNgdB3OWUz-0-83682c667bd0d84df21a437a0dd01e19)
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/56_1.jpg?sign=1734385946-vRZDHGrSF58X86B06WXs1nKXcJbYSUpp-0-52ed3e7604a0115a99416c23c8dd5b9a)
步骤十三:将POJO对象encode成ByteBuffer,调用SocketChannel的异步write接口,将消息异步发送给客户端,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/56_2.jpg?sign=1734385946-6Xc0j3stxLdXMskaPPlMS5SKD4C5lT9B-0-5c79b1caab482ab15ee8ddd36bd1eec4)
通过序列图和关键代码的解说,相信大家对创建NIO客户端程序已经有了一个初步的了解,下面就跟随着我们的脚步,继续看看如何使用NIO改造之前的时间服务器客户端TimeClient吧。