我正在编写一个连接到服务器的Android应用程序(> = 2.3),我遇到了NIO选择器的问题。
Selector selector = SelectorProvider.provider().openSelector();
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
selector.select(); // returns 0 immediately
public abstract int select()
在至少一个通道准备就绪,调用wakeup()或调用线程被中断之前,此方法不会返回。
并且案件不属于这些,但它会返回。 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();
}
它在服务器运行时有效:select()返回1个选定的键,我可以调用finishConnect()来建立连接。但是如果服务器没有运行,则连接被拒绝,select()返回0个选定的键。如果没有选择的密钥,我无法确定下一步该做什么。 (同样,当API文档中描述的select()返回时,这种情况不属于3个类别之一。)
答案 0 :(得分:0)
在注册之前尝试连接套接字。要么在将其置于非阻塞模式之前执行此操作,要么之后执行此操作但注册OP_CONNECT而不是OP_READ并在触发时调用finishConnect():如果它返回true,则取消注册OP_CONNECT并注册OP_READ。