Проблемы с неблокирующим выделением с java.nio - PullRequest
1 голос
/ 20 ноября 2010

Я только начал использовать java.nio и, возможно, использовал его неправильно, поэтому у меня возникла небольшая проблема.

Я пытаюсь написать что-то вроде перенаправителя портов, которое может изменитьтрафик, который проходит через него с использованием различных дополнительных модулей.

Вот как я это делаю:

  1. ConnectionManager - поток, имеющий собственный селектор, зарегистрированный вOP_ACCEPT на ServerSocketChannel.Всякий раз, когда он выбирает что-либо - он создает объект ConnectionProcessor, который управляет соединением.

  2. ConnectionProcessor - поток, который открывает SocketChannel для предопределенной точки пересылки (куда отправлять пакеты от вновь подключенного клиента),Затем он открывает собственный селектор и регистрирует его в OP_READ клиента SocketChannel и OP_READ серверного SocketChannel.

Затем процессор переходит в бесконечный цикл, выбирая данные из селектора и перенаправляя их соответствующим образом.Чтобы определить, куда отправлять данные, он сравнивает SelectionKey.channel () с clientChannel и serverChannel.

Выбор в ConnectionProcessor выполняется с тайм-аутом 5 секунд (select (5000)) - для обработки тайм-аутов.Когда выбирается тайм-аут - он пытается прочитать с обоих каналов, чтобы получить исключение или результат -1.

Теперь вот мои вопросы / проблемы:

  1. Правильно ли использовать ключ.cancel () после обработки ключа?Большинство примеров, которые я видел в Интернете, просто удаляют ключ из списка selectedKeys ().key.cancel () кажется гораздо более подходящим подходом.
  2. Правильно ли иметь несколько селекторов, которые в основном используют один и тот же ServerSocketChannel?Или я должен всегда использовать один селектор и передавать выбранные ключи соответствующим менеджерам?Я имею в виду, что если 3 клиента подключаются одновременно, то это то, что произойдет:

    a) Менеджер создает процессор.Процессор открывает клиентский канал.Процессор регистрирует свой собственный селектор на клиентском канале.б) повторение (а) в) повторение (а)

  3. По какой-то причине даже после того, как хотя бы один клиент подключился к моему серверу пересылки - он не будет обрабатывать сообщения быстрее, чем время ожидания 5000 мсек.Он начинает выбирать, блокируется на 5 секунд, затем переходит ко второй итерации и получает от меня 5-6 сообщений, которые я получил во время предыдущего тайм-аута.Должен ли я винить (1), (2) или какую-то другую причину?
  4. Есть ли какое-либо руководство о том, как все эти вещи nio работают внутренне?Я вроде человека, который понимает, как использовать вещи, только после того, как я полностью понимаю механику внизу.Чтение API не помогает, поскольку оно написано для людей, которые уже знают, как правильно использовать nio.

Спасибо за чтение всего моего вопроса и заранее благодарю за любую помощь.

1 Ответ

0 голосов
/ 20 ноября 2010
  1. Нет.Просто удалите ключ из выбранного набора.Обычно это делается с помощью iterator.remove ().Если вы отмените их, они никогда не будут выбраны снова.

  2. Это бессмысленно.Вам не нужен второй селектор или дополнительная нить.Вот для чего NIO.Вы можете справиться со всем этим с помощью оригинального селектора в исходном потоке.

  3. Возможно, это вызвано странным кодом.Повторите это, как указано выше, и посмотрите, все ли еще произойдет.Если это так, напишите здесь некоторый код.

  4. Вам необходимо прочитать API сокетов Беркли или хорошую книгу, такую ​​как Стивенс, Сетевое программирование Unix или моя ;-)

...