Android:Selector.select()立即返回0

时间:2013-05-05 15:55:16

标签: java android nio

我正在编写一个连接到服务器的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

根据Android API documentation

  

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个类别之一。)

1 个答案:

答案 0 :(得分:0)

在注册之前尝试连接套接字。要么在将其置于非阻塞模式之前执行此操作,要么之后执行此操作但注册OP_CONNECT而不是OP_READ并在触发时调用finishConnect():如果它返回true,则取消注册OP_CONNECT并注册OP_READ。