TCP非阻塞通信

一.SelectableChannel

  1. SelectableChannel支持阻塞和非阻塞模式的channel
    非阻塞模式下的SelectableChannel,读写不会阻塞
  2. SelectableChannel可以向Selector注册监听就绪读和就绪写时间,当Selector发现这些时间触发,就会通知SelectableChannel进行读写
  3. 主要函数
    (1)public SelectableChannel configureBlocking(boolean block):If false then it will be placed non-blocking mode
    (2)public SelectionKey register(Selector sel, int ops, Object att):
    

二.ServerSocketChannel

  1. ServerSocketChannel是ServerSocket的替代类,每个ServerSocketChannel对象对应一个ServerSocket对象,无构造方法。
  2. ServerSocketChannel是SelectableChannel的子类
    (1)public static ServerSocketChannel open()   // 返回ServerSocketChannel对象,该对象未与任何端口绑定,且处于阻塞模式
    (2)serverSocketChannel.socket().bind(int port)  // 把ServerSocketChannel绑定到指定端口
    (3)public final int validOps()  // 返回channel支持的事件,return SelectionKey.OP_ACCEPT;
    

三.SocketChannel

  1. SocketChannel是SelectableChannel和ByteChannel的子类
    (1)public static SocketChannel open()
    (2)public SelectableChannel configureBlocking(boolean block)
         // 返回channel支持的事件,returnreturn(SelectionKey.OP_READ|SelectionKey.OP_WRITE|SelectionKey.OP_CONNECT);
    (3)public final int validOps()  
    (4)public abstract boolean isConnectionPending();   //查看该channel上是否有连接
     /**将字节序列从此通道中读入给定的缓冲区。
        设dst的剩余容量limit-position为r,阻塞模式下的读方法,会尝试读到dst的limit位置或读到输入流末尾或发生异常,否则一直阻塞
        非阻塞模式下,能读多少度多少,立即返回,不会尝试读满dst再返回
        read()方法返回实际上读入的字节数,可能为0,可能为-1,若为-1,表示读到了输入流末尾
     */
    (5)public int read(ByteBuffer dst)         
     /**将src的内容写到channel中,设src的有内容的部分limit-position为r个字节,阻塞模式下,write方法会把r个字节全部写出才能返回,否则阻塞
        非阻塞模式下的write():能输出多少输出多少,可能输出不到r个字节,或输出了0个字节。非阻塞模式下write方法立即返回
     */
    (6)public int write(ByteBuffer src)
    }
    

四.Selector

  1. 一旦ServerSocketChannel和SocketChannel向Selector注册了事件,Selector会监控这些事件是否发生,Selector包含3种SelectionKey集合
    (1)all-keys集合:Selector监听的所有Selectionkey集合,Selector的keys()方法
    (2)selected-keys集合:返回已经被Selector捕获的SelectionKey集合,Selector的selectedKeys()
    (3)cancelled-keys集合:已经被取消的SelectionKey集合,没有方法获取
  2. 当SelectableChannel的register(Selector sel, int ops)方法触发,会新建一个SelectionKey,并把它加入到all-keys集合。如果关闭了与SelectionKey关联的SelectableChannel对象,或执行了SelectionKey的cancel()方法,则把该key加入到cancelled-keys集合,表示该key对象已经失效,在下次执行Selector的select()方法时,被取消的key对象从所有集合删除。
  3. 当执行Selector的select()方法时,若与Selectionkey对象相关的事件发生了,则该key对象就加入到了selected-keys集合。程序直接调用selected-keys集合的remove()方法,或调用它的iterator的remove(),都能从selected-keys集合中删除这个key对象,但不允许调用集合接口的remove()方法从all-keys中删除key对象,否则跑出UnsopportException
(1)public static Selector open()    //Opens a selector
(2)public Set<SelectionKey> keys()  //返回Selector的all-keys集合(UnmodifiableSet)
(3)public int selectNow()			  //返回相关事件已发生的SelectionKey对象数目,采用非阻塞方式,如果没有就返回0
 /**采用阻塞方式,返回已发生的Selectionkey个数,如果一个也没有,就进入阻塞模式,除非其他线程调用了selector.wakeup()*/
(4)public int select()