Simulating SocketTimeoutException

A SocketTimeoutException occurs when a socket object instance has been configured to throw the exception if it receives no data in the prescribed number of milliseconds. The default is 0, which disables the timeout. Reasons you may want to use a timeout value other than 0 include ensuring a given thread is not tied up waiting for a slow remote service to respond.

To be clear, this is not the same issue as a Connection Reset, or a ConnectionTimeoutException. In this case, we successfully connected, but the remote service didn’t respond to us in a timely fashion (or at least as timely as we expected).

import java.net.*;
import java.io.*;
import java.util.*;

class serverSocket {
  public static void main (String args[]) throws Exception {
    ServerSocket ss;
    DataInputStream is;
    PrintStream os;
    ss = new ServerSocket(5000);
    while (true) {
      Socket clientSocket = ss.accept();
      System.out.println("got socket");
      is = new DataInputStream(clientSocket.getInputStream());
      os = new PrintStream(clientSocket.getOutputStream());
      String line = is.readLine();
      Thread.sleep(Integer.parseInt(args[0]));
      os.println("sending back " + line.toUpperCase());
      os.close();
      is.close();
    }
  }
}

class clientSocket {
  public static void main (String args[]) throws Exception {
    Socket s = new Socket("localhost", 5000);
    System.out.println(s.getSoTimeout());
    s.setSoTimeout(Integer.parseInt(args[1]));
    System.out.println(s.getSoTimeout());
    DataInputStream is = new DataInputStream(s.getInputStream());
    PrintStream os = new PrintStream(s.getOutputStream());
    try {
      System.out.println(new Date());
      //Thread.sleep(10000);
      os.println(args[0]);
      String responseLine;
	  while ((responseLine = is.readLine()) != null) {
        System.out.println("Server: " + responseLine);
        os.close();
        is.close();
      }
    }
    catch (Exception e) {
      e.printStackTrace();
    }
    finally {
	  os.close();
	  s.close();
	}
    System.out.println(new Date());
  }
}

You can simulate this with what is below…

c:\Users\showard>java serverSocket 2000
got socket

…and for the client…

c:\Users\showard>java clientSocket steve 1000
0
1000
Sun Nov 27 08:04:22 EST 2016
java.net.SocketTimeoutException: Read timed out
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.socketRead(Unknown Source)
        at java.net.SocketInputStream.read(Unknown Source)
        at java.net.SocketInputStream.read(Unknown Source)
        at java.net.SocketInputStream.read(Unknown Source)
        at java.io.DataInputStream.readLine(Unknown Source)
        at clientSocket.main(serverSocket.java:38)
Sun Nov 27 08:04:23 EST 2016

c:\Users\showard>

Try it with varying values for the sleep in each class to simulate different behaviour.

The server handles the underlying exception as shown below. Specifically, notice that the EPIPE exception is thrown…

29659 08:51:17.673124 accept(7, {sa_family=AF_INET6, sin6_port=htons(57906), inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 8
29659 08:51:17.673179 fcntl(8, F_GETFL) = 0x2 (flags O_RDWR)
29659 08:51:17.673211 fcntl(8, F_SETFL, O_RDWR) = 0
29659 08:51:17.673523 write(1, "got socket", 10) = 10
29659 08:51:17.673600 write(1, "\n", 1) = 1
29659 08:51:17.675158 recvfrom(8,  
29659 08:51:17.686821 <... recvfrom resumed> "s", 1, 0, NULL, NULL) = 1
29659 08:51:17.686876 recvfrom(8, "t", 1, 0, NULL, NULL) = 1
29659 08:51:17.686910 recvfrom(8, "e", 1, 0, NULL, NULL) = 1
29659 08:51:17.686987 recvfrom(8, "v", 1, 0, NULL, NULL) = 1
29659 08:51:17.687050 recvfrom(8, "e", 1, 0, NULL, NULL) = 1
29659 08:51:17.687100 recvfrom(8, "\n", 1, 0, NULL, NULL) = 1
29659 08:51:19.687698 sendto(8, "sending back STEVE", 18, 0, NULL, 0) = 18
29659 08:51:19.687813 sendto(8, "\n", 1, 0, NULL, 0) = -1 EPIPE (Broken pipe)
29659 08:51:19.687875 --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=29658, si_uid=8084694} ---
29659 08:51:19.687915 rt_sigreturn()    = -1 EPIPE (Broken pipe)

Leave a Reply

Your email address will not be published. Required fields are marked *

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