когда java nio селектор разблокируется при вызове select () - PullRequest
3 голосов
/ 15 мая 2011

Я изучаю пакет NIO. Я ссылаюсь на пример NioServer из здесь . Селекторный поток в NioServer.java блоках на

this.selector.select(); 
Iterator<SelectionKey> selectedKeys = this.selector.selectedKeys().iterator();
while (selectedKeys.hasNext()) {
    SelectionKey key = selectedKeys.next();
    selectedKeys.remove();
    if (!key.isValid()) {
        continue;
    }

    if (key.isAcceptable()) {
        this.accept(key);
    } else if (key.isReadable()) {
        this.read(key);
    } else if (key.isWritable()) {
        this.write(key);
    }

Когда подключается удаленный клиент, вызывается this.accept(key) и в этом методе интерес InterestOps изменяется на Чтение и пробуждает селектор. это то, что заставляет селектор выбрать этот канал? Таким образом, мы сигнализируем таким образом, что канал будет выбран?

Теперь предположим, что при записи в селектор канала сокета сигнализируется изменение Интересно, что канал готов к записи. Но предположим, что запись не завершена из-за переполнения буфера сокета, как показано в коде, тогда мы не меняем интерес и сохраняем его как только для записи. тогда когда селектор выберет этот канал?

Ответы [ 2 ]

3 голосов
/ 15 мая 2011
  1. this.accept(key) вызывает serverSocketChannel.accept(), который возвращает новый канал сокета для связи с клиентом.Это этот канал, который зарегистрирован селектором для операций «чтения», т. Е. Селектор теперь имеет две регистрации:

    • исходный ServerSocketChannel с OP_ACCEPT
    • SocketChannel для нового клиента, с OP_READ
  2. Если запись не может быть завершена из-за заполнения буфера, соответствующий SocketChannel остается зарегистрированным с OP_WRITE.Как только клиент прочитает некоторые данные с другого конца, канал будет снова выбран, что позволит нам записать оставшиеся данные, прежде чем перевернуть интерес, установленный обратно в OP_READ.

1 голос
/ 16 мая 2011

OP_WRITE срабатывает, когда в буфере отправки сокета остается место.

Примечание: получение результата write () нулевой длины - единственный случай использования OP_WRITE. Большую часть времени есть место, поэтому OP_WRITE будет продолжать срабатывать. Вы не хотите этого, поэтому обычно вы не регистрируете OP_WRITE для канала: только когда он только что возвратил ноль от записи; и вы отменяете регистрацию, когда эта запись в конце концов завершается через повторный запуск после OP_WRITE.

...