![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=1738867558-HNsVoAafryG5C9A93PQI8MUGKXM9IiXv-0-42d3e6e00045ce76062af0abb53fc7f3)
图2-11 NIO客户端创建序列图
步骤一:打开SocketChannel,绑定客户端本地地址(可选,默认系统会随机分配一个可用的本地地址),示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_1.jpg?sign=1738867558-qsnzorW33YYfuLNZy3Zm6kSZydx3fCzx-0-752d5995dd603867153fd1b3f0e24f47)
步骤二:设置SocketChannel为非阻塞模式,同时设置客户端连接的TCP参数,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_2.jpg?sign=1738867558-i0jKtcHxxZWHaU995XC8Gx1lb5FKcrMX-0-c56ab8b86b6de540ca8d0228c0db83c9)
步骤三:异步连接服务端,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_3.jpg?sign=1738867558-8HkjqFMyRg1WKOD8TOIKL7NC4PrKk5jz-0-4cd5a3eab2fe33ee2fe6c64629cbd43d)
步骤四:判断是否连接成功,如果连接成功,则直接注册读状态位到多路复用器中,如果当前没有连接成功(异步连接,返回false,说明客户端已经发送sync包,服务端没有返回ack包,物理链路还没有建立),示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_4.jpg?sign=1738867558-b7QUGe3g4GksvDVJWiYnJRxeHxdChFEG-0-d9ad3b5c85330c28fe4d494e15dcb11d)
步骤五:向Reactor线程的多路复用器注册OP_CONNECT状态位,监听服务端的TCP ACK应答,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_5.jpg?sign=1738867558-WdIq9h6jlrU4TqJoUm30uLRNXK25oL8A-0-d205d33021d89deea1e78183d372d622)
步骤六:创建Reactor线程,创建多路复用器并启动线程,代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_6.jpg?sign=1738867558-VI6uvnjUk2zVCaheIPD2SUyR2hAzf9jv-0-c8451e2d3857e92fab7e853fdec64d78)
步骤七:多路复用器在线程run方法的无限循环体内轮询准备就绪的Key,代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_7.jpg?sign=1738867558-4AOF1jAEIiq3sK7jwCMPLVlnyN2iWrq5-0-09ce4d9fc532cd14bb5fe2c6f9e41f8d)
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_1.jpg?sign=1738867558-r1L1Hc5QH9IXbtIDWz2immjEcL7lcnHo-0-61d4aec80b2778e8942273837a3fedcc)
步骤八:接收connect事件进行处理,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_2.jpg?sign=1738867558-fUrLZxipGpDaLaAWofDBdJuE2zoaL1xM-0-d80777ed49f2f71cc37638c8a62a5701)
步骤九:判断连接结果,如果连接成功,注册读事件到多路复用器,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_3.jpg?sign=1738867558-baxYyZYgrhWR8t91hxeObI1VVyqaZtvX-0-26c1f7ab4f09f603f76ac1bcb3a9bc5e)
步骤十:注册读事件到多路复用器,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_4.jpg?sign=1738867558-mdBVnOT2jLlgoKywaXenkIqB0UzzSJQS-0-e79c3e75916deb5e2db99ec89c884e3a)
步骤十一:异步读客户端请求消息到缓冲区,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_5.jpg?sign=1738867558-p8CBXqeGkLqeWe2NbizbF7EWq3v7uGQ5-0-33d7a57a31d8acccac586bc653463df6)
步骤十二:对ByteBuffer进行编解码,如果有半包消息接收缓冲区Reset,继续读取后续的报文,将解码成功的消息封装成Task,投递到业务线程池中,进行业务逻辑编排,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_6.jpg?sign=1738867558-Q6WeuLt4jRzOwSI4kbo5VI7Wm90ZiQ8y-0-101bf1102770d269cc9cc0a42f5a662a)
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/56_1.jpg?sign=1738867558-Y0g9EX7lAJPEpzu288jnp8CXrrLc9hk7-0-48ce5ccd9d553f84f03c0ac5df5c4318)
步骤十三:将POJO对象encode成ByteBuffer,调用SocketChannel的异步write接口,将消息异步发送给客户端,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/56_2.jpg?sign=1738867558-aLMKKkYGRCjLVyd5tvSqb2qfTz224lXc-0-268dc781ec7b7c517813e24cd37f56e7)
通过序列图和关键代码的解说,相信大家对创建NIO客户端程序已经有了一个初步的了解,下面就跟随着我们的脚步,继续看看如何使用NIO改造之前的时间服务器客户端TimeClient吧。