1

我正在开发一个 Android 应用程序,尝试从套接字上的一个线程进行非阻塞写入,同时在另一个线程上进行阻塞读取。我正在查看 SocketChannel 文档并试图弄清楚 configureBlocking 究竟做了什么。具体来说,如果我有一个非阻塞的 SocketChannel,并且我使用 socketChannel.socket() 访问附属的 Socket,那么该 Socket 在某种程度上也是非阻塞的吗?还是阻塞了?

换句话说,我可以通过一个非阻塞的SocketChannel作为非阻塞方向,而使用附属的Socket作为另一个方向,从而获得一个阻塞方向和一个非阻塞方向的效果吗?

4

1 回答 1

0

如果Socket有关联的SocketChannel,则不能直接从它的 中读取InputStream。你会得到IllegalBlockingModeException. 见这里

您可以通过将非阻塞 SocketChannel注册Selector并使用select()select(long timeout)来阻塞它们。这些方法通常会阻塞,直到注册的通道准备好(或超时)。

对于不使用选择器的线程,通道仍然是非阻塞的。

从这里修改的例子:

Selector selector = Selector.open();
channel.configureBlocking(false);

// register for OP_READ: you are interested in reading from the channel
channel.register(selector, SelectionKey.OP_READ);

while (true) {
  int readyChannels = selector.select(); // This one blocks...

  // Safety net if the selector awoke by other means
  if (readyChannels == 0) continue;

  Set<SelectionKey> selectedKeys = selector.selectedKeys();
  Iterator<SelectionKey> keyIterator = selectedKeys.iterator();

  while (keyIterator.hasNext()) {
    SelectionKey key = keyIterator.next();

    keyIterator.remove();

    if (!key.isValid()) {
      continue;
    } else if (key.isAcceptable()) {
        // a connection was accepted by a ServerSocketChannel.
    } else if (key.isConnectable()) {
        // a connection was established with a remote server.
    } else if (key.isReadable()) {
        // a channel is ready for reading
    } else if (key.isWritable()) {
        // a channel is ready for writing
    }
  }
}
于 2012-07-05T14:56:32.730 回答