Java BufferedReader readLine()块
使用readLine()接收数据时,即使我在消息末尾加了“\n” 发送消息时使用.flush,读取我的消息的while循环仍然会阻塞。 只有在关闭套接字连接时,它才会离开循环 以下是客户端代码:Java BufferedReader readLine()块,java,sockets,bufferedreader,Java,Sockets,Bufferedreader,使用readLine()接收数据时,即使我在消息末尾加了“\n” 发送消息时使用.flush,读取我的消息的while循环仍然会阻塞。 只有在关闭套接字连接时,它才会离开循环 以下是客户端代码: bos = new BufferedOutputStream(socket. getOutputStream()); bis = new BufferedInputStream(socket. getInputStream()); osw = new Ou
bos = new BufferedOutputStream(socket.
getOutputStream());
bis = new BufferedInputStream(socket.
getInputStream());
osw = new OutputStreamWriter(bos, "UTF-8");
osw.write(REG_CMD + "\n");
osw.flush();
isr = new InputStreamReader(bis, "UTF-8");
BufferedReader br = new BufferedReader(isr);
String response = "";
String line;
while((line = br.readLine()) != null){
response += line;
}
以及服务器的代码:
BufferedInputStream is;
BufferedOutputStream os;
is = new BufferedInputStream(connection.getInputStream());
os = new BufferedOutputStream(connection.getOutputStream());
isr = new InputStreamReader(is);
String query= "";
String line;
while((line = br.readLine()) != null){
query+= line;
}
String response = executeMyQuery(query);
osw = new OutputStreamWriter(os, "UTF-8");
osw.write(returnCode + "\n");
osw.flush();
我的代码在循环时在服务器上阻塞。
谢谢。BufferedReader将继续读取输入,直到它到达末尾(文件、流或源等的末尾)。在这种情况下,“结束”是插座的闭合。因此,只要套接字连接打开,循环就会运行,BufferedReader将只等待更多输入,每次到达'\n'时都会循环。这是因为while循环中的条件:
while((line=br.readLine())!=null)
在每次迭代中读取一行,如果readLine返回null
,则释放循环
如果达到eof(=socked已关闭),readLine仅返回null;如果读取“\n”,readLine将返回字符串
如果要退出readLine上的循环,可以省略整个while循环,只需执行以下操作:
line=br.readLine()
示例:
发生这种情况的原因是InputStream尚未准备好变为红色,因此它会阻塞in.readLine()。
请试试这个:
boolean exitCondition= false;
while(!exitCondition){
if(in.ready()){
if((line=in.readLine())!=null){
// do whatever you like with the line
}
}
}
当然,你必须控制现有的条件
另一个选择是使用nio包,它允许异步(不阻塞)读取,但这取决于您的需要。我尝试了很多解决方案,但唯一不阻塞执行的是以下内容:
BufferedReader inStream = new BufferedReader(new InputStreamReader(yourInputStream));
String line;
while(inStream.ready() && (line = inStream.readLine()) != null) {
System.out.println(line);
}
如果下一个readLine()
调用将阻止执行,则inStream.ready()
将返回false。readLine()和read()将在套接字未关闭时被阻止。所以你应该关闭插座:
Socket.shutdownInput();//after reader
Socket.shutdownOutput();//after wirite
而不是Socket.close() 最好避免使用readline()
。这种方法对于网络通信是危险的,因为某些服务器不返回LF/CR
符号,您的代码将被卡住。当您从文件中读取时,它并不重要,因为您无论如何都会到达文件的末尾,并且流将被关闭
public String readResponse(InputStream inStreamFromServer, int timeout) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(inStreamFromServer, Charsets.UTF_8));
char[] buffer = new char[8092];
boolean timeoutNotExceeded;
StringBuilder result = new StringBuilder();
final long startTime = System.nanoTime();
while ((timeoutNotExceeded = (TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime) < timeout))) {
if (reader.ready()) {
int charsRead = reader.read(buffer);
if (charsRead == -1) {
break;
}
result.append(buffer, 0, charsRead);
} else {
try {
Thread.sleep(timeout / 200);
} catch (InterruptedException ex) {
LOG.error("InterruptedException ex=", ex);
}
}
}
if (!timeoutNotExceeded) throw new SocketTimeoutException("Command timeout limit was exceeded: " + timeout);
return result.toString();
}
publicstringreadresponse(InputStream inStreamFromServer,int timeout)引发异常{
BufferedReader=新的BufferedReader(新的InputStreamReader(inStreamFromServer,Charsets.UTF_8));
char[]buffer=新字符[8092];
布尔timeoutnotexeced;
StringBuilder结果=新建StringBuilder();
final long startTime=System.nanoTime();
while((timeoutnotexceed=(TimeUnit.NANOSECONDS.toMillis(System.nanoTime()-startTime)
它有一个超时,如果需要花费大量时间,您可以中断通信将代码放入try/catch块并关闭finally块中的流/连接。这似乎没有问题。你想知道为什么会发生这种行为吗?如何防止它?如果你只想读一行,为什么要使用while循环?嗯,我不认为这是插座关闭的结果。谢谢现在我看了,我看错了医生!当涉及到非文件流的eof时,文档是相当模糊的。是OP的循环一直读取到EOS,而不是BufferedReader。因此,如果连接打开,但缓冲区中没有行,它还会循环吗?@The_prole-循环将继续。。。某种程度上。它不会退出循环,但是br.readLine()
调用将被阻止,直到有新行可用为止您保存了我的月份。我只需要反转inStream.ready()
和(line=inStream.readLine())!=null
My InputStream是从java.lang获取的。Process@LennoardSilva是的,我的也是从java.lang.Process
中获得的,所以你不知道什么时候用其他方法读不到东西了。你必须确定你使用的协议。大多数协议都指定了它们的终端行为。
public String readResponse(InputStream inStreamFromServer, int timeout) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(inStreamFromServer, Charsets.UTF_8));
char[] buffer = new char[8092];
boolean timeoutNotExceeded;
StringBuilder result = new StringBuilder();
final long startTime = System.nanoTime();
while ((timeoutNotExceeded = (TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime) < timeout))) {
if (reader.ready()) {
int charsRead = reader.read(buffer);
if (charsRead == -1) {
break;
}
result.append(buffer, 0, charsRead);
} else {
try {
Thread.sleep(timeout / 200);
} catch (InterruptedException ex) {
LOG.error("InterruptedException ex=", ex);
}
}
}
if (!timeoutNotExceeded) throw new SocketTimeoutException("Command timeout limit was exceeded: " + timeout);
return result.toString();
}