С неблокирующим SocketChannel, аффилированное Socket блокируется? - PullRequest
1 голос
/ 21 июля 2011

Я занимаюсь разработкой приложения для Android, пытаюсь выполнить неблокирующую запись из одного потока в сокете, в то время как выполняю блокирующее чтение в другом потоке. Я просматриваю документы SocketChannel и пытаюсь понять, что именно делает configureBlocking. В частности, если у меня есть неблокирующий SocketChannel и я получаю доступ к присоединенному Socket с помощью socketChannel.socket (), это Socket также неблокирует каким-либо образом? Или это блокировка?

Другими словами, могу ли я получить эффект одного направления блокировки и одного неблокирующего направления, имея неблокирующий SocketChannel для неблокирующего направления и используя дочерний Socket для другого направления?

1 Ответ

0 голосов
/ 05 июля 2012

Если у Socket есть связанный SocketChannel, вы не можете напрямую читать с него InputStream. Вы получите IllegalBlockingModeException. Смотри здесь .

Вы можете заблокировать неблокирующие SocketChannels, зарегистрировав их в 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
    }
  }
}
...