2011-01-03 4 views
1

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

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

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

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

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

Роб

--EDIT--

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

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

+0

Вы закрываете свои потоки? – npinti

+0

Я попытался закрыть объект записи на стороне клиента после отправки данных в тестовых программах клиент-сервер, и он сработал, но затем сервер вызвал исключение во время выполнения, заявив, что соединение было закрыто, когда он попытался создать объект DataOutputStream написать ответ клиенту. Но в реальной программе, которую я пытаюсь написать, я не контролирую то, что сервер делает или не делает. – Rob

+0

Кроме того, отправка данных заранее не является вариантом, потому что сервер, с которым я связываюсь, этого не делает, и я не имею контроля над кодом сервера. – Rob

ответ

0

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

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

+0

Программа на самом деле является реализацией протокола безопасности Otway-Rees. 3 стороны: ClientA, ClientB и Server. A и B хотят общаться друг с другом, поэтому они используют сервер для аутентификации и предоставления ключа сеанса, который они могут использовать для связи. Это заключительное задание на колледж в прошлом году, и мои реализации должны быть совместимы с моими справочными реализациями моих преподавателей. Пропущенные сообщения кодируются с использованием кодировки NT (Null Terminated encoding). Каждая часть сообщения заканчивается на 00. Но может быть переменное количество частей сообщения. Hmm ... – Rob

+0

, когда вы говорите переменное количество частей, нет ли в протоколе предыдущего указания относительно фактического количества деталей, которые будут поступать? – DaveC

+0

Ну, да, на самом деле, есть. Неплохо подмечено. Если сообщения отправляются надлежащим образом, в сообщение должно быть зафиксировано фиксированное число сегментов, кодированных NT. Это стоит посмотреть, но я не могу помочь, но чувствую, что это просто неправильно. Я действительно должен иметь общую функцию для чтения данных из другого объекта. – Rob

1

Его вы определяете конечное состояние.

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

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

  • Префикс ваши данные с длиной. Сервер прекращает чтение после приема n байтов
  • завершает данные с помощью выделенного байта. Сервер перестает получать, когда найден байт маркера.

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

1

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

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

0

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

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

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

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

Смежные вопросы