简体   繁体   English

套接字,BufferedReader 挂在 readLine()

[英]Socket, BufferedReader hangs at readLine()

I have a server which initially does this:-我有一个最初执行此操作的服务器:-

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

later it passes the socket to another class "foo" This class wait for application specific messages.稍后它将套接字传递给另一个类“foo”这个类等待应用程序特定的消息。

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

My client sends this sequence:我的客户发送这个序列:

  • "bar\\n" “谷仓”
  • "how are u?\\n" “你好吗?\\n”
  • "\\n" "\\n"
  • "passing it to foo\\n" “将它传递给 foo\\n”
  • "\\n" "\\n"

The problem is that sometimes "foo" does not get its response.问题是有时“foo”没有得到它的响应。 It hangs in the readLine() .它挂在readLine()

What is the chance that readLine() in the server is buffering up the data using the read ahead and "foo" class is getting starved?服务器中的readLine()使用readLine()读缓冲数据并且“foo”类变得饥饿的可能性有多大?

If I add a sleep in the client side, it works.如果我在客户端添加睡眠,它会起作用。 But what is the chance that it will always work?但它总是有效的机会有多大?

  • "bar\\n" “谷仓”
  • "how are u?\\n" “你好吗?\\n”
  • "\\n" "\\n"
  • sleep(1000);
  • "passing it to foo\\n" “将它传递给 foo\\n”
  • "\\n" "\\n"

How to fix the problem?如何解决问题? Appreciate any help on this regard.感谢这方面的任何帮助。

eee's solution works perfectly. eee 的解决方案非常有效。 I was trying to read output from an SMTP conversation but it would block on:我试图从 SMTP 对话中读取输出,但它会阻止:

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

Changing to:更改为:

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

I can read everything just fine.我可以很好地阅读所有内容。 br is a BufferedReader object, BTW. br 是一个 BufferedReader 对象,顺便说一句。

I had the same problem and here is my solution:我遇到了同样的问题,这是我的解决方案:

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 "";
}

第一个BufferedReader已经有数据(已从套接字读取,不再从套接字中可用),因此将第一个示例中创建的BufferedReader传递给读取应用程序特定消息的类,而不是创建一个来自套接字的新BufferedReader

The answer might be late but this is the simplest and latest answer in 2020, just use the simple way to receive the data from the socket server or client using the input stream read() method.答案可能晚了,但这是 2020 年最简单最新的答案,只需使用输入流read()方法使用简单的方式从套接字服务器或客户端接收数据即可。

EOFException will be thrown when the client is disconnected or the server closed the connection.当客户端断开连接或服务器关闭连接时将抛出EOFException

private String waitForData() throws IOException {
    String data = "";
    do {
        int c = inputStream.read();
        if (c > -1) data += (char) c;
        else throw new EOFException();
    } while (inputStream.available() > 0);
    return data;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM