zoukankan      html  css  js  c++  java
  • NIO客户端主要创建过程

    NIO客户端主要创建过程:
     
    步骤一:打开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(seletor,SelectionKey.OP_READ,ioHandler);
    }else{
         clientChannel.register(selector,Selection.OP_CONNECT,ioHandler);
    }
    

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

     clientChannel.register(select, 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){
         SelectionKey key = (SelectionKey)it.next();
         //...deal with  I/O event ...
    }
     
    步骤八:接收connect事件进行处理,示例代码如下:
     
    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;
    whiel(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);
  • 相关阅读:
    Grep案例(本地模式)
    Java环境变量 和 Hadoop环境变量 配置
    sudo设置
    Linux配置
    mysql安装(前提:Linux最小化安装)
    test
    Floyd算法【最短路1】
    HttpClient调用接口发送文件
    Spring boot 论坛项目实战_07
    Spring boot 论坛项目实战_06
  • 原文地址:https://www.cnblogs.com/wmcoder/p/7169550.html
Copyright © 2011-2022 走看看