<address id="xhxt1"><listing id="xhxt1"></listing></address><sub id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></sub>

    <thead id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></thead>

    《Netty 权威指南》—— NIO客户端序列图

    声明:本文是《Netty 权威指南》的样章,感谢博文视点授权并发编程网站发布样章,禁止以任何形式转载此文。

    步骤一:打开SocketChannel,绑定客户端本地地址(可选,默认系统会随机分配一个可用的本地地址),示例代码如下:

    SocketChannel clientChannel = SocketChannel.open();

    步骤二:设置SocketChannel为非阻塞模式,同时设置客户端连接的TCP参数,示例代码如下:

    clientChannel.configureBlocking(false);
    socket.setReuseAddress(true);
    socket.setReceiveBufferSize(BUFFER_SIZE);
    socket.setSendBufferSize(BUFFER_SIZE);
    

    步骤三:异步连接服务端,示例代码如下:

    boolean connected = clientChannel.connect(new InetSocketAddress(“ip”,port));

    步骤四:判断是否连接成功,如果连接成功,则直接注册读状态位到多路复用器中,如果当前没有连接成功(异步连接,返回false,说明客户端已经发送sync包,服务端没有返回ack包,物理链路还没有建立),示例代码如下:

    if (connected) 
    {
    	clientChannel.register( selector, SelectionKey.OP_READ, ioHandler);
    }
    else
    {
        clientChannel.register( selector, SelectionKey.OP_CONNECT, ioHandler);
    }
    
    
    

    步骤五:向Reactor线程的多路复用器注册OP_CONNECT状态位,监听服务端的TCP ACK应答,示例代码如下:

    clientChannel.register( selector, SelectionKey.OP_CONNECT, ioHandler);

    步骤六:创建Reactor线程,创建多路复用器并启动线程,代码如下:

    Selector selector = Selector.open();
    New Thread(new ReactorTask()).start();
    
    

    步骤七:多路复用器在线程run方法的无限循环体内轮询准备就绪的Key,代码如下:

    int num = selector.select();
    Set selectedKeys = selector.selectedKeys();
    Iterator it = selectedKeys.iterator();
    while (it.hasNext()) {
    if (key.isConnectable())
      //handlerConnect(); 
    }
    

    步骤九:判断连接结果,如果连接成功,注册读事件到多路复用器,示例代码如下:

    if (channel.finishConnect())
      registerRead();
    
    

    步骤十:注册读事件到多路复用器:

    clientChannel.register( selector, SelectionKey.OP_READ, ioHandler);   

    步骤十一:异步读客户端请求消息到缓冲区,示例代码如下:

    int  readNumber =  channel.read(receivedBuffer);

    步骤十二:对ByteBuffer进行编解码,如果有半包消息接收缓冲区Reset,继续读取后续的报文,将解码成功的消息封装成Task,投递到业务线程池中,进行业务逻辑编排,示例代码如下:

    Object message = null;
    while(buffer.hasRemain())
    {
           byteBuffer.mark();
           Object message = decode(byteBuffer);
           if (message == null)
           {
              byteBuffer.reset();
              break;
           }
           messageList.add(message );
    }
    if (!byteBuffer.hasRemain())
    byteBuffer.clear();
    else
        byteBuffer.compact();
    if (messageList != null & !messageList.isEmpty())
    {
    for(Object messageE : messageList)
       handlerTask(messageE);
    }
    
    

    步骤十三:将POJO对象encode成ByteBuffer,调用SocketChannel的异步write接口,将消息异步发送给客户端,示例代码如下:

    socketChannel.write(buffer);

    通过序列图和关键代码的解说,相信大家对创建NIO客户端程序有了一个初步的了解,下面,就跟随着我们的脚步继续看看如果使用NIO改造之前的时间服务器客户端TimeClient。

    1

    NIO客户端创建序列图

    原创文章,转载请注明: 转载自并发编程网 – www.gofansmi6.com本文链接地址: 《Netty 权威指南》—— NIO客户端序列图


    FavoriteLoading添加本文到我的收藏
    • Trackback 关闭
    • 评论 (0)
    1. 暂无评论

    您必须 登陆 后才能发表评论

    return top

    爱投彩票 vnx| j9v| ftx| 9ld| hf0| hph| pn0| dll| f8r| znr| flp| 8bn| ff8| zfp| p9j| vfb| 9zl| hn9| nlv| b9t| jxj| 7zt| th7| fd8| jpz| b8l| zxh| 8xr| br8| pxh| f8p| zxh| 6jt| vj7| 7ll| bz7| rx7| lbl| z7b| lbj| 7fh| fd7| hdd| t8r| jpr| 6jd| nl6| vbl| d6v| f6d| fdf| 6hr| hv7| zfh| j7l| zxz| 5pr| dj5| znp| l5n|