How to identify end of InputStream in java

Solution 1:

It's looking for more data because nothing's told it that there won't be more data. The other end of the network could send more data at any time.

It's not clear whether you're designing the client/server protocol or just trying to implement it, but typically there are three common ways of detecting the end of a message:

  • Closing the connection at the end of the message
  • Putting the length of the message before the data itself
  • Using a separator; some value which will never occur in the normal data (or would always be escaped somehow)

Personally I favour length-prefixing when possible; it makes the reading code significantly simpler, but still allows multiple messages on the same connection.

(Additionally, I agree with Daniel that you should be using the overload of read which reads a whole buffer at a time, instead of a single byte. This will be much more efficient - but doesn't fundamentally change the nature of your current issue.)

Solution 2:

I think you've actually answered your own question.

The reason you are not exiting the loop is that the end of input stream only happens on the client end after the server end closes its socket. (Or more precisely, after it closes its socket output stream ... or the equivalent ... and the close event has propagated to the client end.)

Until that event happens, it is possible that the server could decide to write more data to the socket. So the client-side read blocks ... until it either gets more data or it sees the protocol event that says that the server end has closed.

(Actually, other events can unblock the client read, but they will all result in an IOException of some kind, and probably a stream that you can't read any more data from.)


Now, if you don't want to close the server end now because you want to send more stuff on the socket later on, you are going to have to change your application protocol to use some kind of framing mechanism. For instance, the server might send a frame (or record, or whatever) consisting of byte count followed by the given number of bytes. Alternatvely, it could use a distinguished byte value or byte sequence to mark the end of a frame.