Noona
Noona

Reputation: 643

setting a timeout for an InputStreamreader variable

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();
    }

Upvotes: 0

Views: 3325

Answers (2)

mdma
mdma

Reputation: 57707

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.

Upvotes: 3

Brian Agnew
Brian Agnew

Reputation: 272287

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

Upvotes: 0

Related Questions