如果没有interestOps()中的OP_WRITE,SelectionKey.isWritable可以为真吗?

时间:2010-09-19 11:03:57

标签: java nio

给定一个SelectableChannel c及其SelectionKey k,k.isWritable()返回,该通道是否已准备好接受对write()的调用。

但是,如果通道接受写入,k.isWritable()会返回true,但是在interestOps中没有设置OP_WRITE吗?

3 个答案:

答案 0 :(得分:1)

不,准备好的操作是兴趣操作的子集。如果key对write不感兴趣,选择器将不会设置其写入就绪op(这并不意味着它不能接受写入。你可以随时调用write()。使用write-ready,write()很可能成功,但是那里也不保证)

答案 1 :(得分:0)

有一个问题,我花了几个小时才弄明白。请考虑以下代码:

SocketChannel socket = SocketChannel.open(new InetSocketAddress("127.0.0.1", 22));
socket.configureBlocking(false);
Selector selector = Selector.open();
SelectionKey selkey = socket.register(selector, 0);
....
selkey.interestOps(SelectionKey.OP_READ);
selector.select(1000);
System.out.println("Selecting r, return " +
  (selector.selectedKeys().contains(selkey) && selkey.isReadable() ? "r" : "") +
  (selector.selectedKeys().contains(selkey) && selkey.isWritable() ? "w" : ""));

打印"选择r,返回w"。所以isWritable()可能是真的,而只有OP_READ感兴趣。如果OP_WRITE包含在先前的select()调用中并且当前的select()返回0,则会发生这种情况,这意味着selkey不会更新。

完整的证明代码在这里:https://gist.github.com/wuyongzheng/43cc9dc07e13124663d1。要运行,您需要在端口22上安装SSH服务器。

答案 2 :(得分:0)

实际上它可以: 如果您首先设置了 OP_WRITE,那么 key.interestOps(0); key.isWritable() 将返回 true。