Simple
handling of network timeouts - JavaWorld
September 1999
Tutorial Details:
Simple handling of network timeouts
Simple handling of network timeouts
By: By David Reilly
Learn just how easy it is to prevent stalled clients and servers
any programmers dread the thought of handling network timeouts. A common fear is that a simple, single-threaded network client without timeout support will balloon into a complex multithreaded nightmare, with separate threads needed to detect network timeouts, and some form of notification process at work between the blocked thread and the main application. While this is one option for developers, it is not the only one. Dealing with network timeouts need not be a difficult task, and in many cases you can completely avoid writing code for additional threads.
When working with network connections, or any type of I/O device, there are two classifications of operations:
Blocking operations : Read or write stalls, operation waits until I/O device is ready
Nonblocking operations : Read or write attempt is made, operation aborts if I/O device is not ready
Java networking is, by default, a form of blocking I/O. Thus, when a Java networking application reads from a socket connection, it will generally wait indefinitely if there is no immediate response. If no data is available, the program will keep waiting, and no further work can be done. One solution, which solves the problem but introduces a little extra complexity, is to have a second thread perform the operation; this way, if the second thread becomes blocked the application can still respond to user commands, or even terminate the stalled thread if necessary.
This solution is often employed, but there is a much simpler alternative. Java also supports nonblocking network I/O, which can be activated on any Socket , ServerSocket , or DatagramSocket . It is possible to specify the maximum length of time that a read or write operation will stall before returning control back to the application. For network clients, this is the easiest solution and offers simpler, more manageable code.
The only drawback to nonblocking network I/O under Java is that it requires an existing socket. Thus, while this method is perfect for normal read or write operations, a connect operation can stall for a much longer period, since there is no method for specifying a timeout period for connect operations. Many applications require this ability; you can, however, easily avoid the extra work of writing additional code. I've written a small class that allows you to specify a timeout value for a connection. It uses a second thread, but the internal details are abstracted away. This approach works well, as it provides a nonblocking I/O interface, and the details of the second thread are hidden from view.
Nonblocking network I/O
The simplest way of doing something often turns out to be the best way. While it is sometimes necessary to use threads and blocking I/O, in the majority of cases nonblocking I/O lends itself to a far clearer and more elegant solution. With only a few lines of code, you can incorporate timeout supports for any socket application. Don't believe me? Read on.
When Java 1.1 was released, it included API changes to the java.net package that allowed programmers to specify socket options. These options give programmers greater control over socket communication. One option in particular, SO_TIMEOUT , is extremely useful, because it allows programmers to specify the amount of time that a read operation will block. We can specify a short delay, or none at all, and make our networking code nonblocking.
Let's take a look at how this works. A new method, setSoTimeout ( int ) has been added to the following socket classes:
java.net.Socket
java.net.DatagramSocket
java.net.ServerSocket
This 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.
Timeout handling on connect operations
If your goal is to achieve complete timeout detection and handling, then you'll need to consider connect operations. When creating an instance of java.net.Socket , an attempt to establish a connection is made. If the host machine is active, but no service is running on the port that is specified in the java.net.Socket constructor, a ConnectionException will be thrown and control will return to the application. However, if the machine is down, or if there is no route to that host, the socket connection will eventually time out on its own much later. In the meantime, your application remains frozen, and there is no way to change the timeout value.
Though the socket constructor call will eventually return, it introduces a significant delay. One way of dealing with this problem is to employ a second thread, which will perform the potentially blocking connect, and to continually poll that thread to see if a connection has been established.
This does not, however, always lead to an elegant solution. Yes, you could convert your network clients into multithreaded applications, but often the amount of extra work required to do this is prohibitive. It makes the code more complex, and when writing only a simple network application, the amount of effort required is difficult to justify. If you write a lot of network applications, you'd find yourself reinventing the wheel frequently. There is, however, a simpler solution.
I've written a simple, reusable class that you can use in your own applications. The class generates a TCP socket connection without stalling for long time periods. You simply call a getSocket method, specifying the hostname, port, and timeout delay, and receive a socket. The following example shows a connection request:
// Connect to a remote server by hostname, with a four second timeout
Socket connection = TimedSocket.getSocket("server.my-network.net", 23, 4000);
If all goes well, a socket will be returned, just like the standard java.net.Socket constructors. If the connection cannot be established before your specified timeout occurs, the method will stop, and will throw an java.io.InterruptedIOException , just as other socket-read operations would when a timeout has been specified using a setSoTimeout method. Pretty easy, huh?
Encapsulating multithreaded network code into a single class
While the TimedSocket class is a useful component in itself, it's also a very good learning aid for understanding how to deal with blocking I/O. When a blocking operation is performed, a single-threaded application will become blocked indefinitely. If multiple threads of execution are used, however, only one thread need stall; the other thread can continue to execute. Let's take a look at how the TimedSocket class works.
Diagram of TimedSocket
When an application needs to connect to a remote server, it invokes the TimedSocket.getSocket() method and passes details of the remote host and port. The getSocket() method is overloaded, allowing both a String hostname and an InetAddress to be specified. This range of parameters should be sufficient for the majority of socket operations, though custom overloading could be added for special implementations. Inside the getSocket() method,
Read
Tutorial at: Click here to view the tutorial
Rate Tutorial: Simple
handling of network timeouts - JavaWorld
September 1999
View Tutorial: Simple
handling of network timeouts - JavaWorld
September 1999
Related
Tutorials:
Integrating Databases
Integrating Databases |
Automating WWW
Exploration
Automating WWW
Exploration |
Java gets serial support with the new javax.comm package
Java gets serial support with the new javax.comm package |
The Jxta solution to P2P
The Jxta solution to P2P |
Use Web services
to integrate Web applications with
EISs
Use Web services
to integrate Web applications with
EISs |
Cache SOAP services on
the client side
Cache SOAP services on
the client side |
Listen to heartbeats using
JMS
Listen to heartbeats using
JMS |
A recipe for cookie management
A recipe for cookie management |
Jtrix: Web
services beyond SOAP
Jtrix: Web
services beyond SOAP |
Test networked
code the easy way
Test networked
code the easy way |
Jini's relevance emerges, Part
2
Jini's relevance emerges, Part
2 |
Should you go
with JMS?
Should you go
with JMS? |
TRMI
TRMI |
Customize
SwingWorker to improve Swing GUIs
Customize
SwingWorker to improve Swing GUIs |
Filtering and Transforming Digital Images
Filtering and Transforming Digital Images
In this Issue
Welcome to the Core Java Technologies Tech Tips for April 7, 2004. Here you\'ll get tips on using core Java technologies and APIs, such as those in Java 2 Platform, Standard Edition (J2SE).
|
JLAN Server v3.3
JLAN Server v3.3
JLAN Server is a high performance JavaTM based file server supporting Windows file sharing (SMB/CIFS), NFS and FTP protocols.
Write your own virtual filesystems with the core server handling all protocol exchanges with the client.
Incl |
Develop WAP Applications with Java Servlets and JavaServer PagesTM
WAP, the Wireless Application Protocol, was designed to take advantage of the several data-handling approaches already in use. WAP integrates the Handheld Device Markup Language (HDML) and the Handheld Device Transport Protocol (HDTP) developed by Unwired |
We are providing Free BSD 5.3 CD's
We are providing Free BSD 5.3 CD's
Free BSD 5.3 CD's
Now Available Free BSD 5.3 CD's
What is Free BSD 5.3?
FreeBSD is an advanced operating system for x86 compatible, DEC Alpha, and PC-98 architectures. It is derived from BSD, the version of |
We are providing Downloadable Version of Gentoo Linux
We are providing Downloadable Version of Gentoo Linux
Gentoo Linux
Now Available Gentoo Linux CD's
We are providing the free downloadable version of Gentoo, which is distributed under GNU public license. You have to pay only for the CD and S&H |
What is WAP? Wireless Application Protocol
What is WAP? Wireless Application Protocol
Tutorial
What is WAP?
W ireless Application Protocol or WAP for short is simply a protocol - a standerized way for delivering Internet data over wireless networks. Thus WAP links Wireless Network with |
|
|
|