Page 2 of 5
Let's take a look at how this works. A new method, setSoTimeout ( int ) has been added to the following socket classes:
java.net.Socketjava.net.DatagramSocketjava.net.ServerSocketThis method allows us to specify a maximum timeout length, in milliseconds, that the following network operations will block:
ServerSocket.accept()SocketInputStream.read()DatagramSocket.receive()Whenever one of these methods is called, the clock starts ticking. If the operation is not blocked, it will reset and only restart once one of these methods is called again; as a result, no timeout can ever occur unless you perform a network I/O operation. The following example shows just how easy it can be to handle timeouts, without resorting to multiple threads of execution:
// Create a datagram socket on port 2000 to listen for incoming UDP packets DatagramSocket dgramSocket = new DatagramSocket ( 2000 ); // Disable blocking I/O operations, by specifying a five second timeout dgramSocket.setSoTimeout ( 5000 );
Assigning a timeout value prevents our network operations from blocking indefinitely. At this point, you're probably wondering
what will happen when a network operation times out. Rather than returning an error code, which might not always be checked
by developers, a java.io.InterruptedIOException is thrown. Exception handling is an excellent way of dealing with error conditions, and allows us to separate our normal
code from our error-handling code. Besides, who religiously checks every return value for a null reference? By throwing an
exception, developers are forced to provide a catch handler for timeouts.
The following code snippet shows how to handle a timeout operation when reading from a TCP socket:
// Set the socket timeout for ten seconds
connection.setSoTimeout (10000);
try
{
// Create a DataInputStream for reading from socket
DataInputStream din = new DataInputStream (connection.getInputStream());
// Read data until end of data
for (;;)
{
String line = din.readLine();
if (line != null)
System.out.println (line);
else
break;
}
}
// Exception thrown when network timeout occurs
catch (InterruptedIOException iioe)
{
System.err.println ("Remote host timed out during read operation");
}
// Exception thrown when general network I/O error occurs
catch (IOException ioe)
{
System.err.println ("Network I/O error - " + ioe);
}
With only a few extra lines of code for a try {} catch block, it's extremely easy to catch network timeouts. An application can then respond to the situation without stalling
itself. For example, it could start by notifying the user, or by attempting to establish a new connection. When using datagram
sockets, which send packets of information without guaranteeing delivery, an application could respond to a network timeout
by resending a packet that had been lost in transit. Implementing this timeout support takes very little time and leads to
a very clean solution. Indeed, the only time that nonblocking I/O is not the optimal solution is when you also need to detect
timeouts on connect operations, or when your target environment does not support Java 1.1.
Using Socket's connect() methodBy Anonymous on August 3, 2009, 10:09 amHi, instead of writing a separate class to handle timeout during connect operation, can't we use the Socket's connect() method instead? According to the API, this...
Reply | Read entire comment
Code Corrections/ImprovementsBy Anonymous on November 8, 2008, 12:30 amCorrection: The call to InetAddress.getByName(String) should not be done because it can block, which makes the solution NOT A SOLUTION. Improvements: The code should...
Reply | Read entire comment
View all comments