![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=1738802871-9Kh98rcteE10Bxc5CMSHAbPcd2NKnHUL-0-f9458c6cfed1b84c2fa1173365bdab8a)
图2-11 NIO客户端创建序列图
步骤一:打开SocketChannel,绑定客户端本地地址(可选,默认系统会随机分配一个可用的本地地址),示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_1.jpg?sign=1738802871-Y8lvopX1quiT2756TfNFiffHZpfWo1AS-0-2deca8c4d4e563782c5f47db1700cc31)
步骤二:设置SocketChannel为非阻塞模式,同时设置客户端连接的TCP参数,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_2.jpg?sign=1738802871-FsoaoZfzDztGCMiVJ00yh65f3C8eYVpH-0-adc691374de3344896711f2a84f31112)
步骤三:异步连接服务端,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_3.jpg?sign=1738802871-rVXxM8mQ2OTxKURvQtiJia8i6xIqsZDx-0-6c885c58a0dee0b070a7d7a184f74831)
步骤四:判断是否连接成功,如果连接成功,则直接注册读状态位到多路复用器中,如果当前没有连接成功(异步连接,返回false,说明客户端已经发送sync包,服务端没有返回ack包,物理链路还没有建立),示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_4.jpg?sign=1738802871-hTSX7eYj23kP696Q2YtT4JQxAWUAtUXE-0-5fa0770aa19adedfcf844a1c306a88b5)
步骤五:向Reactor线程的多路复用器注册OP_CONNECT状态位,监听服务端的TCP ACK应答,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_5.jpg?sign=1738802871-VW3g5txJy4aaLnWqsXn7yOsD1pjtLJL0-0-f662ac0a5e3806abb1272411eb4afffd)
步骤六:创建Reactor线程,创建多路复用器并启动线程,代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_6.jpg?sign=1738802871-UQ8qJrACsSWQhVF2JYczHcQvTYqpM04R-0-ce71fddc2183b804c8134f8fbea74624)
步骤七:多路复用器在线程run方法的无限循环体内轮询准备就绪的Key,代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/54_7.jpg?sign=1738802871-V2yanbBYhF24oSIK3Qu17MoD6yLVMoqb-0-7ebacfdf61c1c3fc5634395d970fa56d)
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_1.jpg?sign=1738802871-stZCarx2HbZAI0RTjY87UcVxwdRe6MXn-0-a757e5bf9f2569307e1a98551a5fdd1a)
步骤八:接收connect事件进行处理,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_2.jpg?sign=1738802871-y52HvNUmx4XaKhlVj1XBu7M3dBD82WSj-0-eef6c2fa88c47a8f11e1633144c6f424)
步骤九:判断连接结果,如果连接成功,注册读事件到多路复用器,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_3.jpg?sign=1738802871-q5g2N06uLY5t40uxK9b0RfZfdGpFg50m-0-e0f26c92145b1581f8971f2839f2909e)
步骤十:注册读事件到多路复用器,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_4.jpg?sign=1738802871-RAQZAD32ppIMY5VkP0QVw0LKXKpZfwDK-0-4360504b5919fbc6163c6f6f1ab08bd1)
步骤十一:异步读客户端请求消息到缓冲区,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_5.jpg?sign=1738802871-43a0aiYBgrMddxuriiZ6L1NazwGcn6GM-0-e0636b463f8a50a89244947c3ffac464)
步骤十二:对ByteBuffer进行编解码,如果有半包消息接收缓冲区Reset,继续读取后续的报文,将解码成功的消息封装成Task,投递到业务线程池中,进行业务逻辑编排,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/55_6.jpg?sign=1738802871-WdUsnYzvM7qDzOoROKp82Uki9rM2Mydv-0-cbb82b0f4d6149a850ed14620606ba0d)
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/56_1.jpg?sign=1738802871-uafIeFMvvWWM2Mja2v5OfpXswykZ5ebS-0-fe7581737c19dc99021acf34009152fe)
步骤十三:将POJO对象encode成ByteBuffer,调用SocketChannel的异步write接口,将消息异步发送给客户端,示例代码如下。
![](https://epubservercos.yuewen.com/1F677E/26763860101459606/epubprivate/OEBPS/Images/56_2.jpg?sign=1738802871-afwoRbXvR04OLeIPLWO1gsRPlIex3ro9-0-18be64894aea256e89a63be00a211bf5)
通过序列图和关键代码的解说,相信大家对创建NIO客户端程序已经有了一个初步的了解,下面就跟随着我们的脚步,继续看看如何使用NIO改造之前的时间服务器客户端TimeClient吧。