Java 套接字,BufferedReader挂起在readLine()上
我有一台服务器,它最初执行以下操作:-Java 套接字,BufferedReader挂起在readLine()上,java,sockets,io,bufferedreader,Java,Sockets,Io,Bufferedreader,我有一台服务器,它最初执行以下操作:- 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()));
for (;;) {
String cmdLine = br.readLine();
if (cmdLine == null || cmdLine.length() == 0)
break;
...
}
之后,它将套接字传递给另一个类“foo”
此类等待特定于应用程序的消息
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
appCmd=br.readLine();
我的客户发送以下序列:
- “栏\n”
- “你好吗?\n”
- “\n”
- “将其传递给foo\n”
- “\n”
readLine()
中
服务器中的readLine()
使用预读来缓冲数据,而“foo”类被饿死的可能性有多大
如果我在客户端添加睡眠,它就会工作。但它始终有效的可能性有多大
- “栏\n”
- “你好吗?\n”
- “\n”
睡眠(1000)代码>
- “将其传递给foo\n”
- “\n”
如何解决这个问题?感谢您在这方面提供的帮助。第一个
BufferedReader
中已经有数据(已从套接字读取,并且不再从套接字可用),因此将第一个示例中创建的BufferedReader
传递给读取应用程序特定消息的类,而不是从套接字创建一个新的BufferedReader
。eee的解决方案非常有效。我试图读取SMTP会话的输出,但它会在以下位置阻塞:
while ((response = br.readLine()) != null) {
...Do Stuff
}
改为:
while (br.ready()) {
response = br.readLine();
...Do Stuff
}
我什么都看得很清楚。br是一个BufferedReader对象,顺便说一句。我也有同样的问题,下面是我的解决方案:
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 "";
}
试试看{
StringBuilder响应=新建StringBuilder();
response.append(“服务器->客户端消息:”).append(CRLF);
//无限循环
while(true){
//检查流是否准备就绪
if(in.ready()){
//实际阅读行
lastLineFromServer=in.readLine();
//如果我们在流的末尾有正常的行为
if(lastLineFromServer!=null){
响应
.append(lastLineFromServer)
.附加(CRLF);
}否则{
返回response.toString();
}
}else{//如果流未就绪
//如果未超过尝试次数
if(尝试次数<尝试次数的最大值){
numberOfTry++;
//等待流准备就绪
睡眠(在下一次尝试之前的最大延迟);
}else{//如果已超出尝试次数
//增加了警告,事情会变得很糟糕
响应
.append(“警告\r\n”)
.append(“服务器发送响应不正确。\r\n”)
.append(“响应可能不完整”)
.附加(CRLF);
返回response.toString();
}
}
}
}捕获(例外情况除外){
例如printStackTrace();
返回“”;
}
答案可能迟了,但这是2020年最简单和最新的答案,只需使用输入流read()
方法从套接字服务器或客户端接收数据即可
当客户端断开连接或服务器关闭连接时,将抛出EOFEException
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;
}
在尝试读取数据之前,您还可以使用BufferedReader的
ready()
检查数据是否准备就绪。在循环中执行此操作如何解决问题?ready()-告诉此流是否准备好读取。通常,我将它与read()
一起使用。我不会将它与readLine()
一起使用,例如:while(true){if(br.ready()){br.read(cb);cb.flip();String msg=cb.toString();if(msg==null)break;}}
cb是具有特定缓冲区大小的CharBuffer
。此技术允许读取缓冲区中允许的行数。有关详细信息。。。我不能那样做。服务器不在我的控制之下。foo类在我的控制下。为什么BufferedReader应该提前阅读?我们不能控制吗?不应BufferedReader提前读取(通过询问),但不清空套接字。请注意,第一个“\n”确保服务器停止读取。它会停止读取,您不能更改它;这是它的读取方法的契约:,int,int)这是对我有效的解决方案。readLine()被无缘无故地卡住了,.ready()对我来说非常有效。在ready()之后使用readLine()时,通常要小心。Ready()告诉您有数据要读取,但并不意味着它是一整行。所以readLine()仍然可以阻止。在我的情况下,br.ready()在第一种情况下始终为false