java取消一个选择键,但在以后重用它
我想先将一个通道注册到选择器,以便仅在connect only上执行select()
,然后在write only上执行
大概是这样的:
SelectionKey key = server.register(selector, SelectionKey.OP_CONNECT);
server.connect(address);
int readyChannels = 0;
while (readyChannels == 0) readyChannels = selector.select(config.connectTimeout);
server.finishConnect();
key.cancel();
key = server.register(selector, SelectionKey.OP_WRITE);
// write something to the channel and check timeout
// with selector.select(config.writeTimeout)
然而,当我到达代码中的第二个register(...)
时,我得到一个CancelledKeyException
还有别的办法吗
正确的方法是每次定义一个新的选择器吗
另外,我知道我可以用key.isWritable()
之类的
# 1 楼答案
如果
finishConnect()
返回false,就不能像返回true那样继续您的问题是,您没有在取消和注册之间调用选择器,因此存在未完成的任务。这里最简单的解决方案是删除cancel和register,直接调整现有选择键的顶部
然而,由于您只是在连接完成之前进行有效的阻塞,因此在阻塞模式下进行连接,然后在后续的I/O中转到非阻塞会更简单:
。。。请注意,如果超时过期,将引发异常
实际上,我很少遇到在客户端以非阻塞模式使用NIO的情况