我正在学习NIO包。我从here引用了NioServer示例。 NioServer.java
中的选择器线程阻塞
this.selector.select();
Iterator<SelectionKey> selectedKeys = this.selector.selectedKeys().iterator();
while (selectedKeys.hasNext()) {
SelectionKey key = selectedKeys.next();
selectedKeys.remove();
if (!key.isValid()) {
continue;
}
if (key.isAcceptable()) {
this.accept(key);
} else if (key.isReadable()) {
this.read(key);
} else if (key.isWritable()) {
this.write(key);
}
当远程客户端连接时,会调用this.accept(key)
并在此方法中引起兴趣
interestOps更改为Read并唤醒选择器。
这是导致选择器选择此频道的原因吗?那么我们用这种方式发出信号来选择频道吗?
现在假设写入套接字通道选择器时通过更改来指示 感兴趣的是频道可以写入。 但是假设在写入没有完成由于套接字缓冲区已满,如代码所示,那么我们不会改变兴趣并将其保持为只写。 然后选择器何时选择此频道?
答案 0 :(得分:3)
this.accept(key)
调用serverSocketChannel.accept()
,返回新套接字通道,以便与客户端进行通信。 此频道已在选择器中注册“读取”操作,即选择器现在具有两个注册:
如果由于缓冲区填满而导致写入无法完成,则相应的SocketChannel仍会在OP_WRITE中注册。一旦客户端从另一端读取一些数据,将再次选择该通道,允许我们在将兴趣集翻转回OP_READ之前写入剩余数据。
答案 1 :(得分:1)
当套接字发送缓冲区中有空间时,OP_WRITE会触发。
NB获得零长度write()结果是使用OP_WRITE的唯一场合。大部分时间都有空间,因此OP_WRITE将继续触发。你不希望这样,所以你通常没有为一个频道注册OP_WRITE:只有当它刚从write返回0时;并且当通过在OP_WRITE之后重新触发该写入最终完成时取消注册它。