Гнездо с установленным таймаутом иногда останавливается при чтении - PullRequest
0 голосов
/ 26 сентября 2011

У меня есть клиент Java (1.6b17 в Windows XP, запущенный через веб-запуск Java), который использует сокет TCP для запроса сервера на основе Java через соединение ADSL. В сокете клиента установлено время ожидания (3000 мс).

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

Клиент создает новый сокет для каждого запроса, выполнив следующие шаги:

  1. Создайте новый сокет, установив время ожидания 3000 мс
  2. Отправить запрос (одна строка текста)
  3. Чтение нескольких строк ответа, закрытие сокета при получении специальной последовательности «конец сообщения» (или ноль)

Вот некоторый (упрощенный) код для иллюстрации:

socket = new Socket(host, port);
socket.setSoTimeout(socketTimeout);

out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

socket.write(cmd);

while (true) {

   line = in.readLine();

   if (line == null) break; 

   if (line.equals("EOL")) break;

   // Store line of text in an ArrayList
}    

socket.close();

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

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

Одно из моих рабочих предположений заключается в том, что это не связано с сетевыми проблемами, так как в противном случае readLine истекло бы, это допустимое предположение?

Также маловероятно, что это будет связано со сборкой мусора. Приложению выделено 512 МБ кучи, а извлекаемые данные состоят из 1600 строк по 100 символов. Я ожидаю, что если проблема, связанная с ГХ или утечками памяти, приведет к общему ухудшению производительности, а не к «залипающему» поведению, которое я вижу, это правильно?

Будем весьма благодарны за любые предложенные стратегии для устранения неполадок.

Спасибо, Фил

Ответы [ 2 ]

2 голосов
/ 26 сентября 2011

Я не видел, чтобы вы получали до 5 минут "паузы".Я могу только представить, что вы получаете много попыток для пакетов.Вы должны быть в состоянии увидеть что-то подобное с Wireshark.Он может дать вам подсказку, если это что-то еще.

Ваше полное время паузы GC на куче 512 МБ должно быть около 0,5 секунд (очень приблизительно)ненадежное соединение, я бы не советовал использовать PrintWriter.Если он получает IOException, он устанавливает флаг, а не выдает исключение.Если вы продолжаете использовать его, он ничего не делает.

1 голос
/ 27 сентября 2011

Время ожидания readLine() должно истечь.Никогда не видел, чтобы не работало ни на одной платформе.Возможно, вы получаете только один символ за раз, с интервалами менее 3 с.Wireshark скажет вам.

Или когда вы читаете строки, возможно, сервер не отправляет новую строку в правильных местах?

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