Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

Simple handling of network timeouts

Learn just how easy it is to prevent stalled clients and servers

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

Page 3 of 5

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, a second thread is created.

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comments (2)
Login
Forgot your account info?

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

Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources