简体   繁体   中英

Infinite Loop in Input Stream

I am reading from an input stream which I am receiving from a server side of a socket. I have no way of knowing what the size of my response will be and I am reading into a byte array this is the code

public static String readString(InputStream inputStream) throws IOException {

    ByteArrayOutputStream into = new ByteArrayOutputStream();
    byte[] buf = new byte[4096];
    for (int n; 0 < (n = inputStream.read(buf));) {
        System.out.println("Got to this point n is "+n);
        into.write(buf, 0, n); 
    }
    into.close();
    System.out.println("passed this point");
    return new String(into.toByteArray(), AddATudeMessage.CHARENC); 
}

write now the numbers 11 and 235 get printed to the console so I assume the server is still writing output into the input stream. it however gets stuck at 235 and nothing seemes to be happending. I tried pausing the main execution thread for as much as 20 seconds at which point i receive 241 bytes from the server and then the same infinite loop reoccurs anyone know what's going on

The way your code is structured, it can work ONLY IF the server closes the socket when it's done. Otherwise your side can never know if the server is done or is merely slow (or there's network congestion).

There are only two ways to solve this problem:

  1. Have the server send the expected length first, then stop reading and proceed when you've received the designated number of bytes.
  2. Have the server send a special data sequence when it's done, some sort of EOF marker that cannot occur in normal data that you can look for to tell you when there's no more data.

Solutions using available() are incorrect because it can return zero if the receive buffer is currently empty but there is still data in transit.

在服务器关闭套接字之前(或可能是元数据包的某些特殊情况inputStream.read(buf)不会返回0。

Consider using int available() (InputStream)
It returns the number of bytes that can be read (or skipped over) from this input stream without blocking by the next caller of a method for this input stream.

The method int InputStream.read() blocks until it receives data from the socket, receives the end of stream sequence or an exception is thrown.

Consider using this statement:

   for (; inputStream.available() > 0;)

In this case, if there is no data available on the socket, the for loop ends and your program can continue. Of course, you will have to adapt your code to do what you want it to do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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