美文网首页
NIO SelectionKey事件理解

NIO SelectionKey事件理解

作者: persisting_ | 来源:发表于2019-05-26 10:54 被阅读0次

在Java NIO编程中,我们可以在通道上注册OP_ACCEPTOP_CONNECTOP_READOP_WRITE,下面我们分别看下各种事件在源码中的注释说明:

  • OP_ACCEPT

Operation-set bit for socket-accept operations. Suppose that a selection key's interest set contains OP_ACCEPT at the start of a selection operatio. If the selector detects that the corresponding server-socket channel is ready to accept another connection, or has an error pending, then it will add OP_ACCEPT to the key's ready set and add the key to its selected-key set.

表明一个SelectionKey包含Accept事件,当selector检测到关联的server-socket channel准备好接受一个连接或者发生错误时,会将该事件加入到该key的'ready set'中,并将该key加入到selected-key set中。

  • OP_CONNECT

Operation-set bit for socket-connect operations. Suppose that a selection key's interest set contains OP_CONNECT at the start of a selection operation. If the selector detects that the corresponding socket channel is ready to complete its connection sequence, or has an error pending, then it will add OP_CONNECT to he key's ready set and add the key to its selected-key set.

当一个socket channel已经准备好完成连接操作或者发生错误时会将该事件加入到该key的'ready set'中,并将该key加入到selected-key set中。

  • OP_READ

Operation-set bit for read operations. Suppose that a selection key's interest set contains OP_READ at the start of a selection operation. If the selector detects that the corresponding channel is ready for reading, has reached end-of-stream, has been remotely shut down for further reading, or has an error pending, then it will add OP_READ to the key's ready-operation set and add the key to its selected-key set.

当一个channel准备好可以被读取(比如socket已经读到了新的字节,其读取缓冲区有尚未被应用读取的数据,可通知应用程序从读取缓冲区进行读取)、已经到达数据流的结尾、远程另一端已经关闭或者发生错误时,会将该事件加入到该key的'ready set'中,并将该key加入到selected-key set中。

  • OP_WRITE

Operation-set bit for write operations. Suppose that a selection key's interest set contains OP_WRITE at the start of a selection operation. If the selector detects that the corresponding channel is ready for writing, has been remotely shut down for further writing, or has an error pending, then it will add OP_WRITE to the key's ready set and add the key to its selected-key set.

当一个channel 准备好进行写入操作(比如原先socket写入缓冲已满,现在已经发送了部分数据,写入缓冲腾出了一些空间,会通知应用程序进行写入)、远程另一端已经关闭或者发生错误时,会将该事件加入到该key的'ready set'中,并将该key加入到selected-key set中。

通过上面的注释,我们可以知道注册事件只是告诉selector在检测到各种事件准备好可以执行时告诉应用,应用可以执行相应的事件,但是注册感兴趣的事件并不是必须的,没有注册事件依然可以进行读取、写入操作,比如读取操作,如果不注册OP_READ事件,应用程序依然可以随时尝试从channel中读取数据,但是并不能保证读取成功,因为可能socket读取缓冲区中可能并不存在数据。但是如果注册了OP_READ事件,在selector检测到该事件准备好了再去读取,则可以最大程度上的保证可以读到数据。写入也是一样的道理,不注册OP_WRITE应用程序也可以随时进行写入,但是可能因为缓冲区满而写入失败,如果注册了OP_WRITE事件,在selector检测到该事件时再进行写入,可以最大程度上保证写入成功。所以说注册相关事件不是必须的,注册了事件可以由selector检测到事件准备好可以执行了再执行相关的事件,避免了许多无效的尝试。

下面我们可以看下Selector.select方法的源码注释:

Selects a set of keys whose corresponding channels are ready for I/O operations. This method performs a blocking selection operation. It returns only after at least one channel is selected, this selector's wakeup method is invoked, or the current thread is interrupted, whichever comes first.

当注册在该Selector上的某个Channel的至少一个事件准备好之后才会返回。因为读取事件是一个被动的事件,应用程序一般会等待读取数据,所在我们一般会注册读取事件,在Channel准备好读取之后告诉应用程序进行读取。而写事件属于一种主动的事件,我们一般不会注册写事件,有要写的数据则直接写数据至Channel即可,写入失败则表示Channel暂时没有准备好被写入,此时应用可以向Channel注册写事件,让Channel在准备好接收写事件时告诉应用,但是一旦应用写完所有的数据,则一般会取消注册的写事件,因为如果数据写完了,但是没有取消注册的写事件,Selector.select方法可能会经常因为有写事件准备完毕而返回,但是应用却无数据需要写。

关于写事件的注册与取消注册,大家可以看下Netty向网络中写数据的实现,正常情况下不会注册写事件,只是在发生写方法返回0,或者写半包的情况下,也即Channel没有准备好写入或者写缓冲已满,但是应用还有数据需要写的情况下才注册写事件,让Channel在准备好写入时及时通知应用,然后应用可以继续写,写完之后会及时取消对写事件的注册。后面会有专文介绍Netty Write原理。

相关文章

  • NIO SelectionKey事件理解

    在Java NIO编程中,我们可以在通道上注册OP_ACCEPT,OP_CONNECT,OP_READ,OP_WR...

  • NIO中Selector与SelectionKey的理解与实践

    在NIO也即是新IO也即是非阻塞IO中,新增了通道Channel和多路复选器selector的概念,通道表示到能够...

  • NIO的SelectionKey(选择键)

    要点 是一个抽象类,表示selectableChannel在Selector中注册的标识.每个Channel向Se...

  • nio个人研究

    nio中的关键是selecter,这是一个选择器,从代码来看实际上就是一个列表,一个包含SelectionKey的...

  • netty源码read

    1. boss event loop 关心SelectionKey.OP_READ | SelectionKey....

  • Java NIO Selector

    1,SelectionKey 1)创建SelectionKey每次channel向selector注册时,会创建一...

  • NIO的write事件及connect事件

    NIO Server端多路复用开发的一般步骤是: 刚开始对NIO的写操作理解的不深,不知道为什么要注册写事件,何时...

  • nio小记 - 轮询SelectionKey为什么要删除

    Selector.select()取出事件集中的全部事件,如果不删除,在下次轮询的时候,调用Selector.se...

  • 高并发知识(三)

    可供选择器监控的通道IO事件类型,包括以下四种: (1)可读:SelectionKey.OP_READ (2)可写...

  • 网络/IO基础

    一、BIO、NIO、AIO的概念 BIO,NIO,AIO的理解1BIO,NIO,AIO的理解2概念解释一个IO操作...

网友评论

      本文标题:NIO SelectionKey事件理解

      本文链接:https://www.haomeiwen.com/subject/ydlxtctx.html