Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you set a timeout on BufferedReader and PrintWriter in Java 1.4?

How does one set a timeout on a BufferedReader and a PrintWriter created using a socket connection? Here is the code I have for the server right now, which works until either the server or the client crashes:

while(isReceiving){
    str = null;
    BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);

    while ((str = br.readLine()) != null){
        System.out.println("Processing command " + str);
        pw.println(client.message(str));
    }
}

Outside the scope of this code I have imposed a socket timeout of 1000ms, which works as intended when waiting for the initial connection. But the program blocks at (str = br.readLine()). If the client hangs or crashes, it never stops blocking unless I terminate the process (which even then doesn't always work).

The client code in question is very similar to this, and is blocking in a similar fashion.

like image 931
Bender the Greatest Avatar asked Jul 22 '11 16:07

Bender the Greatest


People also ask

What is read timeout in Java?

4.2. Why It Occurs? From the client side, the “read timed out” error happens if the server is taking longer to respond and send information. This could be due to a slow internet connection, or the host could be offline.

What is Java socket timeout?

Your Java socket is timing out (throws java. net. SocketTimeoutException: Connection timed out) means that it takes too long to get respond from other device and your request expires before getting response.

What is socket write timeout?

timeout - the socket timeout value passed to the Socket. setSoTimeout() method. The default on the server side is 60000 milliseconds. writeTimeout - a timeout value imposed on socket write operations. This feature is enabled by setting writeTimeout to a value, in milliseconds, greater than zero.

What is read timeout in HTTP?

The HTTP read timeout determines how long the IBM® Watson IoT Platform - Message Gateway Web UI waits before it times out when it is waiting for an HTTP read request to complete. By default, this value is set to 20 seconds.


3 Answers

  1. You need to set a read timeout on the socket, with Socket.setSoTimeout(). This will cause any read method to throw a SocketTimeoutException if the read timeout specified expires. NB Read timeouts are set not on the stream but on the underlying Socket, via Socket.setSoTimeout().

  2. There is no such thing as a write timeout in TCP.

like image 51
user207421 Avatar answered Oct 01 '22 09:10

user207421


You could use SimpleTimeLimiter from Google's Guava library.

Sample code (in Java 8):

BufferedReader br = ...;
TimeLimiter timeLimiter = new SimpleTimeLimiter();

try {
    String line = timeLimiter.callWithTimeout(br::readLine, 10, TimeUnit.SECONDS);
} catch (TimeoutException | UncheckedTimeoutException e) {
    // timed out
} catch (Exception e) {
    // something bad happened while reading the line
}
like image 17
Philipp Jardas Avatar answered Oct 01 '22 09:10

Philipp Jardas


An answer in this question describes an interesting method using a Timer to close the connection. I'm not 100% sure if this works in the middle of a read, but it's worth a shot.

Copied from that answer:

TimerTask ft = new TimerTask(){
   public void run(){
     if (!isFinished){
       socket.close();
     }
   }
};

(new Timer()).schedule(ft, timeout);

isFinished should be a boolean variable that should be set to true when you're done reading from the stream.

like image 5
tskuzzy Avatar answered Oct 04 '22 09:10

tskuzzy