gpt4 book ai didi

java - Android 套接字上的选择器行为异常

转载 作者:太空宇宙 更新时间:2023-11-03 12:01:02 26 4
gpt4 key购买 nike

先决条件:Android 2.2 模拟器。

我有一个完美运行的 Java 代码,它也为 Android 完美编译。但是奇怪的部分来了。特别是,java.nio.Selector 似乎根本不起作用。

第一个问题出现在连接过程中。以下代码适用于 Java,但不适用于 Android(详见下文)。

socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress(remoteAddr, getRemotePort()));

Selector selector = Selector.open();
socketChannel.register(selector, socketChannel.validOps());

// Wait for an event
int selRes = selector.select(timeout);
if (selRes == 1)
{
SelectionKey selKey = (SelectionKey)selector.selectedKeys().iterator().next();
if (selKey.isValid() && selKey.isConnectable()) {
// Get channel with connection request
boolean success = socketChannel.finishConnect();
if (!success) {
selKey.cancel();
}
}
}

我传递了 30000(毫秒,即 30 秒)的超时,但选择立即返回,selres 等于 0(在 Desktop Java 上为 1)。将套接字切换到阻塞模式工作正常(因此地址、端口和其他内容都可以)。

好的,我让连接处于阻塞状态(暂时)。但现在我的 Accept 停止工作 - Selector 不报告传入连接。同样,通过使用阻塞套接字来摆脱 Selector 是可行的。

所以问题是——Selector 是否可以在 Android 中正常工作,或者应该重写代码以完全避免 Selector 和 java.nio?

最佳答案

The following code works on Java

此代码在任何平台上都存在重大问题。

  1. 您没有清除 selectedKeySet。通常这是通过迭代它并调用 Iterator.remove() 来完成的,但在这种情况下,您应该调用 selectedKeys().clear() 因为您没有这样做那,虽然你真的应该:见下文。

  2. 您不应该注册 interestOps=validOps()。您应该注册 OP_CONNECT 直到 finishConnect() 返回 true,然后是 OP_READOP_WRITE,具体取决于您接下来想做什么。

  3. 如果连接不成功,finishConnect() 将抛出一个 IOException,此时您应该关闭 channel 。你没有那样做。

  4. 如果连接尚未完成,finishConnect() 返回 false,在这种情况下您应该继续选择。此时取消 key 没有任何意义。

  5. 如果 selres > 1,您根本不会处理任何选定的键。测试应该是 if (selRes > 0),这并不是真正必要的,因为迭代 selectedKeySet 只会迭代零次;但是 selRes == 0 确实表示 select() 超时,如果您想考虑超时,这会很有用。

关于java - Android 套接字上的选择器行为异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7450758/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com