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:
- Have the server send the expected length first, then stop reading and proceed when you've received the designated number of bytes.
- 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)
is not going to return 0 until the server closes the socket (or maybe some special case of a meta packet or something).
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.