Блокирует ли аффилированный SocketChannel неблокирующий SocketChannel?

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

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


person lacker    schedule 20.07.2011    source источник


Ответы (1)


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

Вы можете заблокировать неблокирующие каналы SocketChannel с помощью регистрация их в Selector и используя select() или выбрать(длительный тайм-аут). Эти методы обычно блокируются до тех пор, пока зарегистрированный канал не будет готов (или не истечет время ожидания).

Канал по-прежнему не блокируется для потоков, не использующих селектор.

Модифицированный пример из здесь:

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
    }
  }
}
person riha    schedule 05.07.2012