SocketTimeoutException

java.net.SocketTimeoutException – How to Solve SocketTimeoutException

In this example we are going to talk about java.net.SocketTimeoutException. This exception is a subclass of java.io.IOException, so it is a checked exception.

From the javadoc we read that this exception :” Signals that a timeout has occurred on a socket read or accept”. That means that this exception emerges when a blocking operation of the two, an accept or a read, is blocked for a certain amount of time, called the timeout. Let’s say that the socket is configured with a timeout of 5 seconds.

If either the accept() or read() method, blocks for more than 5 seconds, a SocketTimeoutException is thrown, designating that a timeout has occurred. It is important to note that after this exception is thrown. the socket remains valid, so you can retry the blocking call or do whatever you want with the valid socket.

1. A simple Cilent-Server application

To demonstrate this exception, I’m going to use the client-server application we’ve seen in java.net.ConnectException – How to solve Connect Exception. It creates two threads. The first one, SimpleServer, opens a socket on the local machine on port 3333. Then it waits for a connection to come in. When it finally receives a connection, it creates an input stream out of it, and simply reads one line of text from the client that was connected. The second thread, SimpleClient, attempts to connect to the server socket that SimpleServer opened. When it does so, it sends a line of text and that’s it.

SocketTimeoutExceptionExample.java:

package com.javacodegeeks.core.net.unknownhostexception;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

public class SocketTimeoutExceptionExample {

	public static void main(String[] args) {

		new Thread(new SimpleServer()).start();
		new Thread(new SimpleClient()).start();

	}

	static class SimpleServer implements Runnable {

		@Override
		public void run() {

			ServerSocket serverSocket = null;
			try {
				
				serverSocket = new ServerSocket(3333);

				serverSocket.setSoTimeout(7000);
				
				while (true) {

					Socket clientSocket = serverSocket.accept();

					BufferedReader inputReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

					System.out.println("Client said :" + inputReader.readLine());
				}

			} catch (SocketTimeoutException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if (serverSocket != null)
						serverSocket.close();

				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		}

	}

	static class SimpleClient implements Runnable {

		@Override
		public void run() {

			Socket socket = null;
			try {

				Thread.sleep(3000);

				socket = new Socket("localhost", 3333);

				PrintWriter outWriter = new PrintWriter(
						socket.getOutputStream(), true);

				outWriter.println("Hello Mr. Server!");

			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (UnknownHostException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {

				try {
					if (socket != null)
						socket.close();
				} catch (IOException e) {

					e.printStackTrace();
				}
			}
		}
	}
}

As you can see, because I’m launching the two threads simultaneously, I’ve put a 3 second delay in SimpleClient for the client to wait before attempting to connect to the server socket, so as to give some time to server thread to open the server socket. Additionally, you will notice that in SimpleServer I’ve specified the timeout to be of 7 seconds using this method : serverSocket.setSoTimeout(7000);.

So, what we expect to happen here, is the communication to finish normally because the client will connect to the server after 3 seconds. That’s 4 seconds before the timeout barrier is reached. If you run the program, you will see this output:

Client said :Hello Mr. Server!

That means that the client, successfully connected to the server and achieved to transmit its text. Now if you wait a bit more, you will see that a

1. An example of SocketTimeoutException

Now, if you keep the above program running, after the Client said :Hello Mr. Server! message is transmitted successfully, you will notice that a SocketTimeoutExceptionis thrown:

Client said :Hello Mr. Server!
java.net.SocketTimeoutException: Accept timed out
	at java.net.DualStackPlainSocketImpl.waitForNewConnection(Native Method)
	at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:135)
	at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398)
	at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:198)
	at java.net.ServerSocket.implAccept(ServerSocket.java:530)
	at java.net.ServerSocket.accept(ServerSocket.java:498)
	at com.javacodegeeks.core.net.unknownhostexception.SocketTimeoutExceptionExample$SimpleServer.run(SocketTimeoutExceptionExample.java:35)
	at java.lang.Thread.run(Thread.java:744)

That’s because, after the SimpleServer serves the first client, it loops back to the accept() method to serve the next client in line, but no one is connected. So, when the time out is reached, SocketTimeoutException is thrown.

Of course, you can choose to handle this exception differently. For example , you can choose to loop back to the accept method, even if the exception is thrown, because the socket remains valid.

In the next example, I will launch two client threads with a certain delay between them, so that one of them sends its message before any exception occurs. The other client thread sends its message after an exception is thrown. Let’s see how you can do that, and pay attention to the server thread:

SocketTimeoutExceptionExample.java:

package com.javacodegeeks.core.net.unknownhostexception;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

public class SocketTimeoutExceptionExample {

	public static void main(String[] args) throws InterruptedException {

		new Thread(new SimpleServer()).start();
		new Thread(new SimpleClient()).start();
			
		Thread.sleep(20000);
		
		new Thread(new SimpleClient()).start();

	}

	static class SimpleServer implements Runnable {

		@Override
		public void run() {

			ServerSocket serverSocket = null;

			try {
				serverSocket = new ServerSocket(3333);
				serverSocket.setSoTimeout(7000);

				while (true) {
					try {
						Socket clientSocket = serverSocket.accept();

						BufferedReader inputReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

						System.out.println("Client said :"+ inputReader.readLine());

					} catch (SocketTimeoutException e) {
						e.printStackTrace();
					}
				}

			} catch (IOException e1) {
				e1.printStackTrace();
			} finally {
				try {
					if (serverSocket != null) {
						serverSocket.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

		}

	}

	static class SimpleClient implements Runnable {

		@Override
		public void run() {

			Socket socket = null;
			try {

				Thread.sleep(3000);

				socket = new Socket("localhost", 3333);

				PrintWriter outWriter = new PrintWriter(
						socket.getOutputStream(), true);

				outWriter.println("Hello Mr. Server!");

			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (UnknownHostException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {

				try {
					if (socket != null)
						socket.close();
				} catch (IOException e) {

					e.printStackTrace();
				}
			}
		}
	}
}

Now if you run the program for a while you will notice that every seven seconds a SocketTimeoutException is thrown :

Client said :Hello Mr. Server!
java.net.SocketTimeoutException: Accept timed out
	at java.net.DualStackPlainSocketImpl.waitForNewConnection(Native Method)
	at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:135)
	at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398)
	at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:198)
	at java.net.ServerSocket.implAccept(ServerSocket.java:530)
	at java.net.ServerSocket.accept(ServerSocket.java:498)
	at com.javacodegeeks.core.net.unknownhostexception.SocketTimeoutExceptionExample$SimpleServer.run(SocketTimeoutExceptionExample.java:38)
	at java.lang.Thread.run(Thread.java:744)
java.net.SocketTimeoutException: Accept timed out
	at java.net.DualStackPlainSocketImpl.waitForNewConnection(Native Method)
	at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:135)
	at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398)
	at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:198)
	at java.net.ServerSocket.implAccept(ServerSocket.java:530)
	at java.net.ServerSocket.accept(ServerSocket.java:498)
	at com.javacodegeeks.core.net.unknownhostexception.SocketTimeoutExceptionExample$SimpleServer.run(SocketTimeoutExceptionExample.java:38)
	at java.lang.Thread.run(Thread.java:744)
Client said :Hello Mr. Server!
java.net.SocketTimeoutException: Accept timed out
	at java.net.DualStackPlainSocketImpl.waitForNewConnection(Native Method)
	at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:135)
	at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398)
	at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:198)
	at java.net.ServerSocket.implAccept(ServerSocket.java:530)
	at java.net.ServerSocket.accept(ServerSocket.java:498)
	at com.javacodegeeks.core.net.unknownhostexception.SocketTimeoutExceptionExample$SimpleServer.run(SocketTimeoutExceptionExample.java:38)
	at java.lang.Thread.run(Thread.java:744)
...
...
...

So as you can see even after the exception is thrown, the socket remains active and receives a message form the second client thread. The above program will keep throwing a SocketTimeoutException every seven seconds.

3. How to Solve SocketTimeoutException

In the above example we’ve shown what causes a SocketTimeoutException in the case of the accept(). The same principles will apply in the case of read(). Now, what can you do to avoid that exception. If the server side application is under your control, you should try yo adjust the timeout barrier so that its more flexible on network delays. You should surely consider doing that especially when your server application will run in a remote machine. Other than that, you can check whatever causes delays in your network, a malfunctioning router etc.

Download Source Code

This was an example on java.net.SocketTimeoutException and how to solve SocketTimeoutException. You can download the source code of this example here : SocketTimeoutExceptionExample.zip

Nikos Maravitsas

Nikos has graduated from the Department of Informatics and Telecommunications of The National and Kapodistrian University of Athens. During his studies he discovered his interests about software development and he has successfully completed numerous assignments in a variety of fields. Currently, his main interests are system’s security, parallel systems, artificial intelligence, operating systems, system programming, telecommunications, web applications, human – machine interaction and mobile development.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button