Copy Link
Add to Bookmark
Report

Java Coffee Break Newsletter Volume 2 Issue 06

         Java Coffee Break Newsletter Volume 2, Issue 6 
http://www.davidreilly.com/jcb/
ISSN 1442-3790

================================================================

In this issue

* Java in the news
* Article : Handling network timeouts in Java

================================================================

In the News

Here are a selection of recent news items that may be of
interest to Java developers.

/*/ Java to support Portable Network Graphics (PNG)

Sun maintains a list of bugs, called the "Bug Parade".
Recently, the bug/feature request for PNG support was
closed. This makes it very likely that the next version
of the Java 2 platform will support the PNG graphics
format.

/*/
Sun expands Java Certification Programme

Sun is set to expand its current Java Certification
Programme, in conjunction with other industry
certifications from IBM, Novell, Oracle, and Netscape.
The new scheme, called Jedi, will involve three levels,
of which Sun Certified Java Programmer is the first.

Details of the new Jedi certification programme are
available from Sun Microsystem's Java site, at
http://java.sun.com/cert-initiative/

/*/ Legal victories in Sun/Microsoft Java lawsuit

Both parties have cause to celebrate, as well as to be
concerned, after Judge Ronald Whyte issued three
preliminary rulings in the lawsuit. While Microsoft
appears to have violated their Java license, they are
free to develop a cleanroom implementation.

For further coverage, see CNET's spin, at
http://www.news.com/News/Item/0,4,37017,00.html?st.ne.fd.
gif.d

/*/
Microsft assists developers of compiler and third
party tools

In a bid to encourage support for Microsoft J/Direct in
third party Java development tools, such as compilers,
IDEs, and JVMs, the "Developer Tools Interoperability
Kit"
has been released. This kit includes specification
and compatibility tests for Microsoft J/Direct.

The kit can be downloaded from
http://www.microsoft.com/java/

================================================================

Handling network timeouts in Java

When writing network applications in a stable
and controlled environment, it is easy to
forget what the real world is like. Slow
connections, traffic build ups, or power
interruptions can cause network connections
to stall or even die. Few programmers take
the time to detect and handle network timeouts,
but avoiding the problem can cause client
applications to freeze, and for threads in
servers to block indefinitely. There are,
however, easy ways to handle network timeouts.
In this article, I'll present two techniques
for overcoming the problem of network timeouts:
threads and setting a socket option for
timeouts. -- David Reilly

Overview

Handling timeouts is one of those tasks that people generally
leave to the last moment. In an ideal world, we'd never need
them. In an intranet environment, where most programmers do
their development, it's almost always unnecessary. However, on
the Internet, good timeout handling is critical. Badly behaved
clients may go offline and leaving server threads locked, or
overloaded servers may stall, causing a network client to block
indefinitely for input. For these reasons, it is necessary to
detect and handle network timeouts.

I've identified two relatively simple solutions to the problem
of handling network timeouts. The first solution involves the
use of second thread, which acts as a timer. This solution
results in a slight increase in complexity, but is backwards
compatible with JDK1.02. The second solution is by far, much
simpler. It takes only a few lines of code, by setting a socket
option, and catching a timeout exception. The catch (isn't there
always one) is that it requires a JDK1.1 or higher virtual
machine.

Solution One : Using a timer thread

Many network software (particularly servers), are written as
multi-threaded applications. However, a client can also use
multiple threads. One solution to handling network timeouts is
to launch a secondary thread, the 'timer', and have it cancel
the application gracefully if it becomes stalled. This prevents
end users from becoming confused when the application stalls - a
good error message will at least let them know the cause of the
problem.

Listing One shows a Timer, which can be used in networking
applications to handle timeouts gracefully. Once the timer is
started, it must be reset regularly, such as when data is
returned by a server. However, if the thread that reads from a
remote network host becomes stalled, the timer will exit with an
error message. For those who require a custom handler, the
timeout() method may be overridden to provide different
functionality.

Listing One - Timer.java

/**
* The Timer class allows a graceful exit when an application
* is stalled due to a networking timeout. Once the timer is
* set, it must be cleared via the reset() method, or the
* timeout() method is called.
* <p>
* The timeout length is customizable, by changing the 'length'
* property, or through the constructor. The length represents
* the length of the timer in milliseconds.
*
* @author David Reilly
*/

public class Timer extends Thread
{
/** Rate at which timer is checked */
protected int m_rate = 100;

/** Length of timeout */
private int m_length;

/** Time elapsed */
private int m_elapsed;

/**
* Creates a timer of a specified length
* @param length Length of time before timeout occurs
*/

public Timer ( int length )
{
// Assign to member variable
m_length = length;

// Set time elapsed
m_elapsed = 0;
}


/** Resets the timer back to zero */
public synchronized void reset()
{
m_elapsed = 0;
}

/** Performs timer specific code */
public void run()
{
// Keep looping
for (;;)
{
// Put the timer to sleep
try
{
Thread.sleep(m_rate);
}
catch (InterruptedException ioe)
{
continue;
}

// Use 'synchronized' to prevent conflicts
synchronized ( this )
{
// Increment time remaining
m_elapsed += m_rate;

// Check to see if the time has been exceeded
if (m_elapsed > m_length)
{
// Trigger a timeout
timeout();
}
}

}
}

// Override this to provide custom functionality
public void timeout()
{
System.err.println ("Network timeout occurred....
terminating"
);
System.exit(1);
}
}

To illustrate the use of the Timer class, here is a simple TCP
client (Listing Two) and server (Listing Three). The client
sends a text string across the network, and then reads a
response. While reading, it would become blocked if the server
stalled, or if the server took too long to accept the
connection. For this reason, a timer is started before
connecting, and then reset after each major operation. Starting
the timer is relatively simple, but it must be reset after each
blocking operation or the client will terminate.

// Start timer
Timer timer = new Timer(3000);
timer.start();

// Perform some read operation
......

// Reset the timer
timer.reset();

The server is relatively simple - it's a single-threaded
application, which simulates a stalled server. The server reads
a response from the client, and echoes it back.To demonstrate
timeouts, the server will always "stall" for a period of twenty
seconds, on every second connection. Remember though, in real
life, server timeouts are entirely unpredictable, and will not
always correct themselves after several seconds of delay.

Listing Two
import java.net.*;
import java.io.*;

/**
* SimpleClient connects to TCP port 2000, writes a line
* of text, and then reads the echoed text back from the
server.
* This client will detect network timeouts, and exit
gracefully,
* rather than stalling.
* Start server, and the run by typing
*
* java SimpleClient
*/

public class SimpleClient
{
/** Connects to a server on port 2000,
and handles network timeouts gracefully
*/

public static void main (String args[]) throws Exception
{
System.out.println ("Starting timer.");
// Start timer
Timer timer = new Timer(3000);
timer.start();

// Connect to remote host
Socket socket = new Socket ("localhost", 2000);
System.out.println ("Connected to localhost:2000");

// Reset timer - timeout can occur on connect
timer.reset();

// Create a print stream for writing
PrintStream pout = new PrintStream (
socket.getOutputStream() );

// Create a data input stream for reading
DataInputStream din = new DataInputStream(
socket.getInputStream() );

// Print hello msg
pout.println ("Hello world!");

// Reset timer - timeout is likely to occur during the
read
timer.reset();

// Print msg from server
System.out.println (din.readLine());

// Shutdown timer
timer.stop();

// Close connection
socket.close();
}
}

Listing Three
import java.net.*;
import java.io.*;

/**
* SimpleServer binds to TCP port 2000, reads a line
* of text, and then echoes it back to the user. To
* demonstrate a network timeout, every second connection
* will stall for twenty seconds.
*
* Start server by typing
*
* java SimpleServer
*/

public class SimpleServer extends Thread
{
/** Shall we stall? flag */
protected static boolean shallWeStall = false;

/** Socket connection */
private Socket m_connection;

/**
* Constructor, accepting a socket connection
* @param connection Connection to process
*/

public SimpleServer (Socket connection)
{
// Assign to member variable
m_connection = connection;
}

/** Starts a simple server on port 2000 */
public static void main (String args[]) throws Exception
{
ServerSocket server = new ServerSocket (2000);

for (;;)
{
// Accept an incoming connection
Socket connection = server.accept();

// Process in another thread
new SimpleServer(connection).start();
}
}

/** Performs connection handling */
public void run()
{
try
{
DataInputStream din = new DataInputStream (
m_connection.getInputStream() );

PrintStream pout = new PrintStream (
m_connection.getOutputStream() );

// Read line from client
String data = din.readLine();

// Check to see if we should simulate a stalled
server
if (shallWeStall)
{
// Yes .. so reset flag and stall
shallWeStall = false;

try
{
Thread.sleep (20000);
} catch (InterruptedException ie ) {}
}
else
{
// No.... but we will next time
shallWeStall = true;
}

// Echo data back to clinet
pout.println (data);

// Close connection
m_connection.close();
}
catch (IOException ioe)
{
System.err.println ("I/O error");
}
}
}

Solution Two : Simplified timeout handling with socket options

A significantly easier solution to handling network timeouts is
to set a socket option. Socket options allow programmers greater
control over socket communication, and are supported by Java as
of JDK1.1. One socket option in particular, SO_TIMEOUT, is
extremely useful, because it allows programmers to specify an
amount of time that a read operation will block for, before
generating an java.io.InterruptedIOException, which can be
easily caught to provide a timeout handler.

We can specify a value for SO_TIMEOUT, by using the
setSoTimeout() method. This method is supported by
java.net.Socket, java.net.DatagramSocket, and
java.net.ServerSocket. This is important, as it means we can
handle timeouts in both the client and the server. The
setSoTimeout accepts as its sole parameter an int, which
represents the number of milliseconds an operation may block
for. Settings this value to one thousand will result in timeouts
after one second of inactivity, whereas setting SO_TIMEOUT to
zero will allow the thread to block indefinitely.

// Set SO_TIMEOUT for five seconds
MyServerSocket.setSoTimeout(5000);

Once the length for the timeout is set, any blocking operation
will cause an InterruptedIOException to be thrown. For example,
a DatagramSocket that failed to receive packets when the
receive() method is called, would throw an exception. This makes
it easy to separate our timeout handling code from the task of
communicating via the network.


The full article is available for free from the Java Coffee
Break
http://www.davidreilly.com/jcb/articles/network_timeouts/

================================================================

The Java Coffee Break Newsletter is only sent out to email
subscribers who have requested it, and to readers of the
comp.lang.java.programmer and comp.lang.java.help newsgroups.

If you'd like to receive our newsletter, and get the latest
Java news, tips and articles from our site, then get your FREE
subscription from

http://www.davidreilly.com/jcb/newsletter/

If you are an email subscriber and no longer wish to receive
the JCB Newsletter, please unsubscribe using the WWW form
located at

http://www.davidreilly.com/jcb/newsletter/unsubscribe.html

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT