Чтение сокета Java не получает запись, отправленную сразу после установления соединения - PullRequest
0 голосов
/ 16 марта 2011

У меня есть клиент и сервер Java, я пытаюсь написать тесты Junit.В своих тестах я жду установления соединения между сервером и клиентом, а затем пишу сообщение от сервера к клиенту для проверки связи.Я обнаружил, что если я сделаю запись немедленно, она не будет получена, и клиент останется заблокированным методом BufferedReader.readLine ().Если я добавляю сон на полсекунды между соединением сокета и вызовом записи с сервера, все работает отлично.

Я пытаюсь выяснить, зачем нужен сон.Я знаю, что сокет сгенерирован и bufferedReader обернут вокруг его входного потока до того, как мой метод waitForConnection () вернется с отчетом, что сервер и клиент соединились.Мое лучшее предположение заключается в том, что мне нужно убедиться, что я вызываю метод readLine клиента, прежде чем сервер вызовет его метод записи;но я думал, что сокеты будут автоматически буферизовать входящие данные, которые не были сразу прочитаны?

Может ли кто-нибудь подтвердить (или опровергнуть) мое подозрение, что я должен гарантировать, что клиент вызвал readline, прежде чем сервер вызовет запись.И если это требуется, может ли кто-нибудь предложить способ, с помощью которого сервер может определить, готов ли клиент принимать входные данные, не выполняя другое рукопожатие в дополнение к рукопожатию TCP?

edit: я должен был сказать это раньше, но тест, который не проходит, проверяет способность восстановить соединение, когда старое не удается.После того, как клиент подключился, мой фиктивный сервер уничтожил сокет / serverSocket и через несколько секунд снова открыл новый serverSocket и принял новое соединение от клиента.После того, как клиент устанавливает соединение во второй раз, запись завершается неудачно.Мои предыдущие тесты, которые просто проверяют соединение, происходят, и клиент получает запись, похоже, работает.

Спасибо

Ответы [ 4 ]

0 голосов
/ 08 марта 2017

У меня была та же проблема, и я даже думал о громоздком процессе подтверждения.Но на самом деле вам не нужно ждать вызова read, и проблема находится в другом месте.

В моем случае я делегировал вызов чтения в отдельный поток.Но тест jUnit завершился успешно, хотя read в потоке

  • еще не вызывался,
  • все еще находился в процессе чтения или
  • дажехуже: поток даже не достиг состояния выполнения

, когда основной поток jUnit уже завершился.

Чтобы доказать мое предположение, вы можете поместить ожидание в конец блокавместо этого проверьте «между соединением сокета и сервером запись вызова» и отправка / прием все равно будут работать.

Просто для полноты: не забудьте позвонить flush()

0 голосов
/ 16 марта 2011

Как вы уничтожаете сокет сервера в своем модульном тесте? Может быть, вы закроете сокет перед отправкой данных.

0 голосов
/ 04 августа 2014

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

Вы этого не делаете.Сервер может отправлять в любое время.

И если это требуется

Это не так.

Ваша проблема в другом месте.

0 голосов
/ 16 марта 2011

Вам не нужно проверять, что клиент читает, прежде чем запись на сервер.Сетевой уровень будет буферизовать трафик до тех пор, пока он не будет использован.

Обязательно вызовите сброс в OutputStream после отправки сообщения на сервере.В противном случае фактический сетевой вызов может быть выполнен только после заполнения буфера.Кроме того, использование readLine может быть проблематичным.Возможно, вы не используете символ завершения строки?Возможно, лучше использовать более простой метод read (char []).

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