Search code examples
javasocketsinputstreamblocking

Java DataInputStream read does not return


I am implementing a simple client/server reader and I am using DataInputStream to read everything as bytes, and then take care of the parsing later.

So this is my reading code:

String line;
String requestString = "";

//client is a Socket that is initialized elsewhere
DataInputStream inputData = new DataInputStream(client.getInputStream());
byte [] messageByte = new byte[1024];
int counter = 0;
  while(true) {  
    int bytesRead = inputData.read(messageByte, counter, 1024-counter);
    counter = (counter + bytesRead)%1024;
    if(bytesRead == -1) {
      System.out.println("Breaking out of loop");
      break;
    }
    line = new String(messageByte, 0, bytesRead);
    System.out.println( "GOT > " + line );
  }

It is able to read the messages, but can't break out of the loop because the last call to read doesn't return.


Solution

  • Sockets will block until there is no more input. InputStream is just an interface exact behaviour depends on its provider implementation. Set timeout on your socket so that exception is thrown if there is no input in certain period.

    Here is quotation from javadoc on Socket, notice that it describes the behaviour of the read from a socket as blocking operation until a timeout is reached:

    public void setSoTimeout(int timeout)
                      throws SocketException
    

    Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect. The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout.

    The solution:

    Besides checking for -1 which is OK. Set timeout on the socket and ensure the exception when thrown is processed correctly.