0

I have a server running that accepts connections made through client sockets, I need to read the input from this client socket, now suppose the client opened a connection to my server without sending anything through the server's socket outputstream, in this case, while my server tried to read the input through the client socket's inputstream, an exception will be thrown, but before the exception is thrown i would like a timeout say of 5 sec, how can I do this? currently here's how my code looks like on the server side:

try 
    {
        InputStreamReader clientInputStream = new InputStreamReader(clientSocket.getInputStream());
        int c;
        StringBuffer requestBuffer = new StringBuffer();
        while ((c = clientInputStream.read()) != -1) 
        { 
            requestBuffer.append((char) c);
            if (requestBuffer.toString().endsWith(("\r\n\r\n")))
                break;
        }
        request = new Request(requestBuffer.toString(), clientSocket);
    } 
    catch (Exception e) // catch any possible exception in order to keep the thread running
    {
        try 
        {
            if (clientSocket != null)
                clientSocket.close();
        } catch (IOException ex) 
        {
            ex.printStackTrace();
        }
        System.err.println(e);
        //e.printStackTrace();
    }

2 Answers 2

3

The textbook answer is to set soTimeout on your socket, which you can do. However, that does not work in all cases. A friend of mine once demonstrated this by pulling out my network cable. I'd set soTimeout with a value of 30 seconds, yet my app just hung there, forever.

To get dependable timeouts, it is best to separate your I/O onto anther thread. If the thread doesn't come back with a response within the given time, you can try interrupting it, closing the streams and ultimately destroying the thread. This won't get you any further but, will try to clean up the streams. Once timeout has occurred, you will need to consider the current communication lost, restablish a connection and resend the previous command to repeat the communication. A command-pattern can help here. It's much easier to do if the commands are idempotent and can be executed multiple times. Being able to repeat failed requests can be used to deal with intermittent I/O errors.

Sign up to request clarification or add additional context in comments.

3 Comments

great, then setSoTimeout, which works most of the time, but also be prepared to interrupt your thread if it does not come back within time. Note that in some cases not even interrupt will get your thread out of waiting for I/O (I know it should, but in practice it doesn't) so if interrupt does not give you back control, be prepared to just close the streams, ditch the thread and start over with a new connection.
I want to keep the thread running since it's contained in a threadpool that I prepared and started upon starting the server. and in my comment to Brian I said that the exception was still thrown immediately.
I suspect your timeout didn't work because you set it after the connection had already been created. You need to either (a) include timeout in socket constructor, which automatically connects or (b) call no-arg socket constructor, then call setSoTimeout, then call socket.connect with SocketAddress. See berni's answer: stackoverflow.com/questions/6656666/…
0

Have you tried setting the timeouts on the underlying socket ? See Socket.setSoTimeout(). From the doc:

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

4 Comments

no but I tried doing this now: clientSocket.setSoTimeout(5000); but an exception is still thrown immediately.
what's the exception class and message?
java.net.SocketException: Connection reset and its source is this line: while ((c = clientInputStream.read()) != -1)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.