Сокет, BufferedReader зависает в readLine () - PullRequest
13 голосов
/ 13 мая 2011

У меня есть сервер, который изначально делает это: -

BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
for (;;) {
  String cmdLine = br.readLine();
  if (cmdLine == null || cmdLine.length() == 0)
     break; 
  ...
}

, позже он передает сокет другому классу "foo". Этот класс ожидает сообщений, специфичных для приложения.

 BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
 appCmd=br.readLine();

Мой клиент отправляет эту последовательность:

  • "bar \ n"
  • "Как дела? \ N"
  • "\ n"
  • "передача его в foo \ n"
  • "\ n"

Проблема в том, что иногда "foo" не получает ответ.Он зависает в readLine().

Какова вероятность того, что readLine() на сервере буферизует данные с использованием опережающего чтения и класс "foo" становится голодным?

ЕслиЯ добавляю сон на стороне клиента, он работает.Но какова вероятность того, что он всегда будет работать?

  • "bar \ n"
  • "Как дела? \ N"
  • "\ n"
  • sleep(1000);
  • "передача его в foo \ n"
  • "\ n"

Как исправитьэта проблема?Ценю любую помощь в этом отношении.

Ответы [ 3 ]

22 голосов
/ 17 февраля 2014

Решение Eee работает отлично. Я пытался прочитать вывод из SMTP-диалога, но он заблокировал бы:

while ((response = br.readLine()) != null) {
    ...Do Stuff
}

Изменение на:

while (br.ready()) {
    response = br.readLine();
    ...Do Stuff
}

Я могу читать все просто отлично. br - это объект BufferedReader, кстати.

2 голосов
/ 13 мая 2011

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

0 голосов
/ 05 сентября 2018

У меня была такая же проблема, и вот мое решение:

try {
    StringBuilder response = new StringBuilder();
    response.append("SERVER -> CLIENT message:").append(CRLF);
    //Infinite loop
    while (true) {
        //Checks wheather the stream is ready
        if (in.ready()) {
            //Actually read line 
            lastLineFromServer = in.readLine();
            //If we have normal behavior at the end of stream
            if (lastLineFromServer != null) {
                response
                        .append(lastLineFromServer)
                        .append(CRLF);
            } else {
                return response.toString();
            }
        } else {//If stream is not ready
            //If number of tries is not exceeded
            if (numberOfTry < MAX_NUMBER_OF_TRIES) {
                numberOfTry++;
                //Wait for stream to become ready
                Thread.sleep(MAX_DELAY_BEFORE_NEXT_TRY);
            } else {//If number of tries is exeeded
                //Adds warning that things go weired
                response
                        .append("WARNING \r\n")
                        .append("Server sends responses not poroperly.\r\n")
                        .append("Response might be incomplete.")
                        .append(CRLF);
                return response.toString();
            }
        }
    }
} catch (Exception ex) {
    ex.printStackTrace();
    return "";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...