Клиентский сервер Java отправляет байты, получатель слушает бесконечно - PullRequest
1 голос
/ 03 января 2011

Я пытаюсь написать программу на Java для Windows, которая предполагает связь с серверной программой, расположенной на чужой машине. Моя программа успешно подключается к серверу, успешно записывает на него байтовый массив и ожидает ответа.

Я знаю, что сервер печатает байты (ответ) обратно мне по одному байту за раз.Я пытался использовать объект DataInputStream с различными методами (read, readByte и т. Д.), Я пытался использовать объект BufferedReader с его методами (read, readLine и т. Д.), Но все объекты чтения и различные методы, которые я использовалвсе сталкиваются с одной и той же проблемой.

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

Эта проблема, похоже, влияет на все методы, которые у меня есть.пытался.Я проводил тесты с простой клиентской программой и серверной программой, каждая длиной около 40 или 50 строк, где клиент подключается к серверу и отправляет на него несколько байтов.Все методы, которые я пытался использовать для чтения с сервера, приводят к той же проблеме, о которой говорилось выше (сервер зависает в ожидании большего ввода от клиента, даже если он отправил все свои данные).

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

-Rob

- EDIT -

В конце я остановился на алгоритме, который прекращает чтение байтов, отслеживая количество сегментов сообщений, которыебыли прочитаны (сегменты разделены двумя нулевыми значениями: 00) и сравниваются с числом ожидаемых сегментов (переданных функции чтения в качестве аргумента).Это не идеальный метод, но он работает, и у меня больше нет времени работать над программой.

Спасибо за помощь всем!

Ответы [ 4 ]

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

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

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

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

Это вы, кто определяет конечное условие.

Один общий, простой случай - простое закрытие соединения (это определение протокола печати P9100). Теперь чтение должно вернуть -1.

В противном случае вы можете

  • префикс ваших данных с длиной. Сервер прекращает чтение после получения n байтов
  • завершает данные выделенным байтом. Сервер прекращает прием при обнаружении байта маркера.

Это ваша проблема или я неправильно понял?

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

Чтобы ваше приложение могло продолжать работать, вы можете прочитать данные ответа в отдельном потоке.

Если на самом деле нет другого способа узнать, когда сообщение закончилось, вы можете использовать тайм-аут.т. е. как только вы получаете данные, и вы больше не получаете их в течение 100 мс или 1 секунды, вы можете предположить, что у вас все это есть.

Лучшая альтернатива - вы пишете свой код, поэтому не нужно знать, когдаконец сообщенияОн может просто обрабатывать каждый «ответ» по мере их поступления, обрабатывая их как потоковые события по мере их поступления.

Когда данные возвращаются, кажется, вы предполагаете, что вам не нужно знать, когда данные полны.

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

Другой вариант (не очень хороший, но может показаться, что вам не до этого) - попытаться воздействовать на полученные данные. Например, если вы получаете сериализованный объект, вы можете попытаться десериализовать его. Если это удастся, вы получили все свои данные. Если нет, попробуйте прочитать еще.

Можете ли вы рассказать нам больше о том, какие данные вы получаете? Есть ли что-нибудь в данных, которые вы можете проверить, чтобы определить, является ли сообщение завершенным?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...