Я только что начал использовать java.nio и, вероятно, использовал его неправильно, поэтому у меня возникли небольшие проблемы с ним.Проблемы с неблокирующим выбором с java.nio
Я пытаюсь написать что-то вроде Port Forwarder, который может модифицировать трафик, который проходит через него, используя различные дополнительные модули.
Вот как я это делаю:
ConnectionManager - поток, который имеет собственный селектор, который зарегистрирован в OP_ACCEPT на ServerSocketChannel. Всякий раз, когда он выбирает что угодно - он создает объект подключения ConnectionProcessor, который управляет соединением.
ConnectionProcessor - нить , что открывает SocketChannel с заранее определенной передней точки (где посылать пакеты из недавно подключенного клиента). Затем он открывает свой собственный селектор и регистрирует его для OP_READ клиента SocketChannel и сервер SocketChannel OP_READ.
Затем процессор переходит в бесконечный цикл, выбирая данные из селектора и перенаправляя его соответствующим образом. Чтобы определить, куда отправлять данные, он сравнивает SelectionKey.channel() с clientChannel и serverChannel.
Выбор в ConnectionProcessor производится с таймаутом 5 секунд (выберите (5000)) - для обработки тайм-аутов. При выборе тайм-аута - он пытается прочитать из обоих каналов, чтобы получить исключение или -1 результат.
Теперь вот мои вопросы/проблемы:
- ли право использовать key.cancel() после обработки ключа? Большинство примеров, которые я видел в Интернете просто удалите ключ из selectedKeys(). key.cancel() , похоже, намного лучше подходит.
Правильно ли иметь несколько селекторов , которые в основном используют тот же сервер ServerSocketChannel? Или я должен всегда использовать одиночный селектор и передавать выбранные ключи соответствующим менеджерам? То, что я имею в виду, что если 3 клиенты подключаются одновременно, то это то, что будет:
а) менеджер создает процессор. Процессор открывает клиентский канал. Процессор регистрирует свой собственный селектор на клиентский канал. б) повторение (а) в) повторение (а)
- По какой-то причине, после того, как даже один клиент подключается к моей экспедитора - это не будет обрабатывать сообщения быстрее, чем 5000msec тайм-аут. Он начинает выбирать, блокируется в течение 5 секунд, а затем идет на вторую итерацию и получает мне 5-6 сообщений, которые я получил во время предыдущего таймаута. Должен ли я обвинять (1), (2) или какую-то другую причину?
- Есть ли какое-либо руководство по поводу того, как все это работает внутри? Я как бы человек, который понимает, как использовать вещи только после того, как я полностью пойму механику внизу. API чтения не помогает, поскольку он написан для людей, которые уже знают правильный способ использования nio.
Спасибо за то, что прочитали весь мой вопрос и заблаговременно за любую помощь.
НИО является утомительным, чтобы получить правильный. Я бы рекомендовал [XNIO] (http://jboss.org/xnio) или [MINA] (http://mina.apache.org/) или insert-NIO-wrapper-library здесь, чтобы сохранить некоторые головные боли и получить более последовательная база. Одной из «простых» проблем с NIO является необходимость пробуждения выбора на готовых к записи данных (что отличается от того, что канал способен писать). Счастливое кодирование. – 2010-11-20 11:26:17
Hm ... Итак, если я что-то помещаю на канал и пытаюсь выбрать из него одновременно, он не будет отправлять какие-либо данные до тех пор, пока выбор не будет завершен? Это страшно, собираюсь проверить XNIO и MINA. Спасибо за совет. – bezmax
Нет, он этого не говорил. Он имеет в виду различные проблемы, возникающие при обработке записей, и существуют различные способы их обработки. Самый простой способ - сделать все записи inline в избранном потоке, но даже у этого есть свои причуды. – EJP