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

    NIO服务端主要创建过程:
     
    步骤一:打开ServerSocketChannel,用于监听客户端的连接,它是所有客户端连接的副管道,示例代码如下:     
    ServerSocketChannel acceptorSvr = ServerSocketChannel.open();
    

    步骤二:绑定监听端口,设置连接为非阻塞模式,示例代码如下: 

    acceptTorSvr.socket().bind(new InetScoketAddress(InetAddress.getByName(IP),port));
    acceptorSvr.configureBlocking(false);
    

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

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

    步骤四:将ServerSocketChannel注册到Reactor线程的多路复用器Selector上,监听ACCEPT事件,示例代码如下: 

    SelectionKey key = acceptorSvr.register(selector,SelectionKey.OP_ACCEPT,ioHandler);
    

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

    int num = selector.selector();
    Set selectedKeys = selector.selectedKeys();
    Iterator it = selectedKeys.iterator();
    while(it.hasNext()){
         SelectionKey key = (SelectionKey)it.next();
         //....deal with i/o event ...
    }
    

    步骤六:多路复用器监听到有新的客户端接入,处理新的接入请求,完成TCP三次握手,建立物理连接,示例代码如下: 

    SocketChannel channel = svrChannel.accept();
    

    步骤七:设置客户端链路为非阻塞模式,示例代码如下: 

    channel.configureBlocking(false);
    channel.socket().setReuseAddress(true);
    ...
    

    步骤八:将新接入的客户端连接注册到Reactor线程的多路复用器上,监听读操作,读取客户端发送的网络消息,示例代码如下: 

    SelectionKey key = socketChannel.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 : nessageList){
             handlerTask(messageE); 
         }
    }
     
    步骤十一:将POJO对象encode成ByteBuffer,调用SocketChannel的异步write接口,将消息异步发送给客户端,示例代码如下: 
    socketChannel.write(buffer); 
  • 相关阅读:
    tyvj 1031 热浪 最短路
    【bzoj2005】 [Noi2010]能量采集 数学结论(gcd)
    hdu 1394 Minimum Inversion Number 逆序数/树状数组
    HDU 1698 just a hook 线段树,区间定值,求和
    ZeptoLab Code Rush 2015 C. Om Nom and Candies 暴力
    ZeptoLab Code Rush 2015 B. Om Nom and Dark Park DFS
    ZeptoLab Code Rush 2015 A. King of Thieves 暴力
    hdoj 5199 Gunner map
    hdoj 5198 Strange Class 水题
    vijos 1659 河蟹王国 线段树区间加、区间查询最大值
  • 原文地址:https://www.cnblogs.com/wmcoder/p/7169004.html
Copyright © 2011-2022 走看看