2.3.4 NIO客户端序列图
NIO客户端创建序列图如图2-11所示。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/53_1.jpg?sign=1739371185-DlALGUrDoRpGzKNcn3NU7DBzKjKpkT7t-0-85bad31e122dc1d79f6197de0b3cfb27)
图2-11 NIO客户端创建序列图
步骤一:打开SocketChannel,绑定客户端本地地址(可选,默认系统会随机分配一个可用的本地地址),示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_1.jpg?sign=1739371185-4TGskRPEabv91i9QKuDwe4EFeATcRHoG-0-ec96de5078c9f3152ae7e07fd33ab183)
步骤二:设置SocketChannel为非阻塞模式,同时设置客户端连接的TCP参数,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_2.jpg?sign=1739371185-nl4SwbqZvn0Eu5G303EDkrx3rTrl7Oo7-0-bac874a188de0a4d9e767e739aa993f6)
步骤三:异步连接服务端,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_3.jpg?sign=1739371185-1TRWlyMGIrMYOSPwaE3nDIs9bIHutkof-0-2105d37af9a932adcaba933cfdb5db42)
步骤四:判断是否连接成功,如果连接成功,则直接注册读状态位到多路复用器中,如果当前没有连接成功(异步连接,返回false,说明客户端已经发送sync包,服务端没有返回ack包,物理链路还没有建立),示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_4.jpg?sign=1739371185-KWl3HcTIUFGPGaQS6Hbn0Qdq1Vn81Tp3-0-1bb61e39793d58ea456b45c146426fa5)
步骤五:向Reactor线程的多路复用器注册OP_CONNECT状态位,监听服务端的TCP ACK应答,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_5.jpg?sign=1739371185-o6QrmcsbcDzXmS6eLg68TM8uWjeA5FJH-0-6983e66835fa11dcb64368361b39f2a0)
步骤六:创建Reactor线程,创建多路复用器并启动线程,代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_6.jpg?sign=1739371185-8SY3Tcnj8rWMKGUCOA6xVrVqs4c0W7bO-0-a103c649f88907e412c272c11b85c04a)
步骤七:多路复用器在线程run方法的无限循环体内轮询准备就绪的Key,代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_7.jpg?sign=1739371185-uKw5prV6aQPEjEqTo1lHI0scSjLc0ndl-0-1656f4ad30be9da1c3e1b070d44d02d2)
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_1.jpg?sign=1739371185-w1cOP7ueqLpAqfHND1VjOEzmBkHYKPv2-0-b00332de4723056c2c3a7a5111465c49)
步骤八:接收connect事件进行处理,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_2.jpg?sign=1739371185-NMT6E9ugMtbEuaVBI4zSMd0MS4TlTGam-0-c93169e2781d209e290db82e193557df)
步骤九:判断连接结果,如果连接成功,注册读事件到多路复用器,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_3.jpg?sign=1739371185-ECYOwqegyGs5vOeQrLaC3QZUim2z5Aek-0-b4ad533c79660898e1a9e24a7a820f07)
步骤十:注册读事件到多路复用器,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_4.jpg?sign=1739371185-JIVjATQEDXsBLlZpnAS3GRLOBNEMtWwk-0-a75236dfbe799a885de614f61ac9573e)
步骤十一:异步读客户端请求消息到缓冲区,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_5.jpg?sign=1739371185-UHcrGWSa8IUKXH2LyLUMv48FysLhOlya-0-b33f5b52d73b663383cb611879a9f0e9)
步骤十二:对ByteBuffer进行编解码,如果有半包消息接收缓冲区Reset,继续读取后续的报文,将解码成功的消息封装成Task,投递到业务线程池中,进行业务逻辑编排,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_6.jpg?sign=1739371185-Q5hyIvOzSPbpYxRMj7xck3W67hf2naIj-0-a419cc751f0c0059058e1e2bd8dd4484)
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/56_1.jpg?sign=1739371185-b4yMHny5oB1HHFzgU5atmGYqpbrehQzv-0-c1715b97590332b7d46355d84182e5e7)
步骤十三:将POJO对象encode成ByteBuffer,调用SocketChannel的异步write接口,将消息异步发送给客户端,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/56_2.jpg?sign=1739371185-dmzwxFFOdQrJNwOcYyTMzNGnBvwLmA4A-0-b5fe4475c978ec99c2c553f747114ec8)
通过序列图和关键代码的解说,相信大家对创建NIO客户端程序已经有了一个初步的了解,下面就跟随着我们的脚步,继续看看如何使用NIO改造之前的时间服务器客户端TimeClient吧。