how to prevent java.net.ConnectException: Connection timed out?

sivaram picture sivaram · Jan 8, 2013 · Viewed 31.4k times · Source

can any body explain java.net.ConnectException: Connection timed out

Caused by: java.net.ConnectException: Connection timed out 
    at java.net.PlainSocketImpl.socketConnect(Native Method) 
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:337) 
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:198) 
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:180) 
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:391) 
    at java.net.Socket.connect(Socket.java:579) 
    at sun.reflect.GeneratedMethodAccessor11.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at net.sourceforge.jtds.jdbc.SharedSocket.createSocketForJDBC3(SharedSocket.java:289) 
    at net.sourceforge.jtds.jdbc.SharedSocket.(SharedSocket.java:250) 
    at net.sourceforge.jtds.jdbc.ConnectionJDBC2.(ConnectionJDBC2.java:297)

Answer

linski picture linski · Jan 8, 2013

This means that the driver tried to open connection to that IP on that port, but there was no one listening on that port, so no one answered hence the "connection timed out" message.

As Arunn P Johny suggested, if you open up a command line and run

telnet localhost 4545

and it responds like this

Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused

this means that no one is listening. E.g. Trying to open a socket(database connection) on that port will result in connection timed out exception. (Port 4545 was chosen because there isn't anything listening on it on my computer)

If it responds with anything else e.g.

telnet localhost 3306

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

It means that the port is open and that the exception won't be thrown. (There is MySQL listening on 3306 on my computer).

Most probably the IP and port in your database connection string(see here for reference) is wrong, e.g. set to some port that no database is listening on.

See this answer and an explanation for HTTP Error 408 Request timeout (it is the same error).

EDIT:

I initially gave a wrong answer (as EJP pointed out). Both errors happen on TCP level while establishing connection:

  • Connection refused means that there is no one listening on the given port
  • Connection timeout means that the connection couldn't be established, or, as stated by EJP that connection attempt timed out.

Suppose you have the following line in Java, eventually JDBC driver does (something like) this at some point:

Socket s = new Socket(IP,PORT);

Before this line is executed the (TCP) connection is closed. After this line gets executed, and no exception gets thrown, the connection is established (as stated in apidoc for constructor). While this line is executing this is what actually happens (it is called TCP three-way handshake):

TCP threeway handshake

Let's review two possible situations.

First, let's say that the IP is reachable (e.g. ping IP from the command line starts printing response times to console) but there is not process listening on the PORT. The three-way handshake will occur as drawn but as soon the connection gets established the server won't find any of his processes listening on that port and will initiate closing of the connection immediatley - Connection refused will be thrown.

This is the only possible outcome for this exception.

Now, let's assume the IP isn't reachable. The client will send the connection request but will never receive connection granted. After a given period of time (timeout) has passed the Connection timeout will be thrown. Consider the following code:

    String reachableIP = "127.0.0.1";
    String unreachableIP = "10.192.0.1";
    int connTimeout = 1000;
    long duration = 0;        
    try {
        duration = System.currentTimeMillis();            
        new Socket().connect(new InetSocketAddress(unreachableIP, 3306), connTimeout);
    }
    catch (Exception e) {
        duration = System.currentTimeMillis() - duration;           
        System.out.println("connect attempt duration measured in ms:" + duration);
        System.out.println(e.getMessage());
    }

outputs:

connect attempt duration measured in ms:1009
connect timed out

This is also stated in apidoc for connect method. So, this exception gets thrown if the destination IP is unreachable. However, reasons for unreachability of a computer on a network can be numerous. The first thing that comes to my mind is that the host is turned off, or to rephrase EJP's comment:

There are numerous causes, like the backlog queue filling up, or network connectivity problems that could lead to this exception.