3
我正在编写一个连接到服务器的Android应用程序(> = 2.3),并且我遇到了NIO选择器的问题。Android:Selector.select()立即返回0
Selector selector = SelectorProvider.provider().openSelector();
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
selector.select(); // returns 0 immediately
公共抽象INT的select()
此方法不返回,直到至少一个信道准备好时,唤醒()被调用或调用线程被中断。
和的情况下落入这些都不但它返回。 select()不像规范中描述的那样运行,我认为这是一个错误。
编辑
我在下面EJP的评论改变了代码:
socketChannel.register(selector, SelectionKey.OP_CONNECT);
socketChannel.connect(serverAddress);
while (true) {
selector.select();
for (SelectionKey key: _selector.selectedKeys()) {
if (key.isConnectable())
finishConnect(key);
...
}
selector.selectedKeys().clear();
}
当服务器在运行它的工作原理:选择()1个选择键返回,我可以打电话finishConnect()建立连接。但是如果服务器没有运行,连接被拒绝,select()会返回0个选定的键。如果没有选定的密钥,我无法确定接下来要做什么。 (并再次,这种情况并不在API文档中描述的select()返回落入3个类别之一。)
感谢您的回复。如果服务器关闭并且连接被拒绝,该怎么办?在这种情况下,select()返回0并且selectedKeys()为空,那么如何知道连接失败并处理了这种情况? – 2013-05-06 08:34:18
问题是,当连接失败时,select()会返回没有正确设置selectedKeys()的值。即使连接失败,也应该选择密钥,以便随后调用finishConnect()可以捕获异常以知道它失败。这就是在Java文档中指定的OP_CONNECT的行为,如果Andoroid不遵循它,它就像一个错误。 – 2013-05-06 10:37:42
你错过了这一点。在上面的代码中,您正在调用select * *连接套接字。这是回到前面。在调用connect()之后,isConnectable()发生*,并且这是一个信号,您应该尝试调用finishConnect()。这不是您现在可以调用connect()的信号。你不需要等待任何事情。 – EJP 2013-05-06 23:16:55