У меня есть работающий клиент-серверный аппарат, который может успешно подключаться и отправлять сообщения друг другу с помощью NIO.
Сейчас меня смущает только то, как я должен продолжать чтение, когда socketChannel.read() возвращает ноль.
У меня есть протокол, который отправляет первые 4 байта в качестве ожидаемого количества входящих байтов. Даже с такой суммой я сталкиваюсь с потенциальной проблемой.
Для тестирования. Однако бывают случаи, когда я могу прочитать что-то вроде:
5 // Read 5 bytes when calling socketChannel.read()
0 // Read 0 bytes when calling socketChannel.read() immediately after
Когда я наткнулся на ноль, я предположил, что закончил чтение и должен ждать, пока ко мне не поступят дополнительные данные.
Однако, когда я это делаю, OP_READ, похоже, не срабатывает, когда я позже снова выполняю selectNow(). Я проверил ключ, и его readyops() иinterestops() установлены на 1 (что соответствует OP_READ), но он не хочет распознавать, что пришло время снова читать.
Я обнаружил, что если я продолжу цикл чтения, я могу получить что-то вроде:
5 // socketChannel.read()
0 // socketChannel.read()
7 // socketChannel.read() (Done since I have all my bytes)
0
0
0
...
Я запутался здесь, потому что это означает одно из:
Там нет данных, поэтому доступный 0 является законным, но затем, когда поступают остальные данные, селектор отказывается возвращать ключ с помощью selectNow()
Данные все есть, но почему-то возвращает 0 при чтении.
Должен ли я перерегистрировать канал после того, как selectNow() вернет его как активный ключ? (Хотя мне не приходилось переключаться с OP_CONNECT на OP_READ... так что, думаю, нет). Я чувствую, что слепое вращение в цикле опасно и приведет к трате циклов обработки.
Мне что, просто продолжать их опрашивать? Это сбивает меня с толку, когда на самом деле срабатывает OP_READ.
bb.clear();
между чтением. Я обновлю код рабочим примером и прокомментирую, где это было вызвано. - person Water   schedule 25.05.2015