Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java BufferedReader readLine()块_Java_Sockets_Bufferedreader - Fatal编程技术网

Java BufferedReader readLine()块

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

使用readLine()接收数据时,即使我在消息末尾加了“\n” 发送消息时使用.flush,读取我的消息的while循环仍然会阻塞。 只有在关闭套接字连接时,它才会离开循环

以下是客户端代码:

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();
}