Как сделать блок readInt () на входном потоке байтов? - PullRequest
3 голосов
/ 03 февраля 2011

У меня есть входной поток, поступающий из черного ящика (скажем, B). Все сообщения, поступающие из этого потока, являются сериализованными двоичными данными, и каждое сообщение начинается с четырехбайтового числа int. Большая часть данных регистрируется и работает 24 часа в сутки. Я прочитал эти четыре байта, используя метод readInt (). Теперь, иногда, основной поток завершает работу с EOFException и завершает работу программы.

После исследования этого я обнаружил, что это происходит, когда во входном потоке во время readInt () меньше четырех байтов. Я предполагаю, что буфер не заполняется достаточно быстро между последовательными чтениями. Некоторые из возможных решений, о которых я думаю, включают проверку доступности () перед чтением (занимает слишком много циклов, учитывая количество данных) или перезапуск при возникновении исключения (звучит как плохое программирование). Думаю, если бы я мог заблокировать использование readInt (), это был бы лучший способ. Я посмотрел на реализацию readInt (), но опять-таки все сводится к блокировке с read ().

Кто-нибудь знает лучшее решение?

Ответы [ 3 ]

1 голос
/ 03 февраля 2011

Любой блокирующий вызов в иерархии вызовов «связан», чтобы сделать все вызовы вверх по цепочке блокирующими, поскольку оба вызова являются частью одного и того же потока выполнения. Метод readInt для DataInputStream выполняет четыре вызова метода read базового входного потока, который, несомненно, будет блокироваться, пока данные не будут доступны, поэтому вы боитесь, что буфер не заполняется достаточно быстро не кажется логичным.

Я сталкивался с подобными исключениями в тех случаях, когда серверный процесс либо умирает, либо сбрасывает соединение, и в этом случае клиент заканчивает чтение -1 и выдает исключение. Вы поглощаете какие-то исключения в своем клиент-серверном коде? Ваши журналы показывают что-нибудь подозрительное?

1 голос
/ 03 февраля 2011

Я считаю, что вы используете DataInputStream. Этот класс создает исключение EOFException в ситуации, когда поток, который он переносит, возвращает -1 из метода read () (который фактически блокируется, пока не будут доступны входные данные).

Полагаю, вам следует посмотреть, почему чтение основного потока возвращает с -1 в первую очередь.

0 голосов
/ 03 февраля 2011

Базовый интерфейс InputStream требует блокирования чтения. Получаемое исключение EOFException генерируется, когда readInt () встречает маркер конца потока, так как возврат неполного целого будет плохой идеей, если он выдает * 1003. * E nd O f F ил Исключение.

EOFException выбрасывается, потому что другой конец потока достиг своего конца, был закрыт или больше не подключен. Вы должны проверить, разрывает ли черный ящик соединение.

Поскольку поток является сетевым, для вашего сокета может быть установлено время ожидания, в этом случае попробуйте изменить значение сокета SOTimeout .

...