java.net.SocketTimeoutException vs java.net.ConnectException

10,833

Solution 1

Also came here looking for the same answer, seemingly the docs can be easily misinterpreted:

Connects this socket to the server with a specified timeout value. A timeout of zero is interpreted as an infinite timeout. The connection will then block until established or an error occurs.

The key part that I overlooked in this is "an error"... going to the source I can see how Java's connect() is actually invoking the Linux connect():

if (timeout <= 0) {
    connect = connect(args...);
    if (connect == -1 && errno == EINPROGRESS) {
        connect = poll(args...);
        // try again on EINTR
    }
} else {
    // Go to non-blocking mode for a timeout.
    connect = connect(args...);

    if (connect!=0) {
        // not EINPROGRESS? -> throw ConnectException
        while (!connect || !error || timedout) {
            connect = poll(args...);
            // error / timedout handling
        }
        if (timedout) {
            // throw SocketTimeoutException
        }
    }
}

/* report the appropriate exception */
if (error) {
    //EINVAL; throw SocketException
    //EINTR; throw InterruptedIOException
    //EPROTO; throw ProtocolException
    //ECONNREFUSED;ETIMEDOUT; throw ConnectException
    //EHOSTUNREACH; throw NoRouteToHostException
    //EADDRNOTAVAIL; throw NoRouteToHostException
    //EISCONN, EBADF, other; throw SocketException
}

i.e. I think SocketTimeoutException is being thrown when the network is slow, or the host doesn't respond at all. Checking man connect, I can see that ECCONNREFUSED must be thrown when "No-one listening on the remote address", i.e. and an ICMP tells us so.

This means that if like me, you were trying to use the timeout to connect to a (localhost) socket that wasn't ready to be connected to, you are SOL'd.

Solution 2

You will get a SocketTimeoutException if you specify a timeout on connect(), or if you've called setSoTimeout() on a Socket or ServerSocket and a read() or accept() times out, respectively. In the case of connect(), this is a serious problem: what you're trying to connect to either doesn't exist or is behind a firewall, and you can't tell which.

You will get connection refused if the peer actively refused your connection request, which usually means there is nothing listening at the port you specified. Note that unlike a timeout, this means a response was received, and it was negative.

Solution 3

ConnectException is thrown on packet filter/firewall etc.

SocketTimeoutException is thrown when you have set a specific timeout on your socket, and it has not received anything before the timeout.

Example with a ServerSocket:

ServerSocket serverSocket = new ServerSocket... // Create server socket
serverSocket.setSoTimeout(1000);  
serverSocket.accept();

If the ServerSocket has not received anything within 1000 ms it will throw a SocketTimeoutException. Note that this exception is thrown for all sockets that use timeouts, not only ServerSocket. This means that a Socket object that throws a SocketTimeoutException hasn't got anything back from the called server before the timeout.

To fix the problem you can either make sure that the server responds quicker, or set a higher timeout value.

Share:
10,833

Related videos on Youtube

cacert
Author by

cacert

Updated on June 24, 2022

Comments

  • cacert
    cacert about 2 years

    When connecting to a server with a Java client socket I had this two different connection timeout exceptions.

    Caused by: java.net.SocketTimeoutException: connect timed out
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:381) 
    
    Caused by: java.net.ConnectException: Connection refused: connect 
        at java.net.PlainSocketImpl.socketConnect(Native Method) 
        at java.net.PlainSocketImpl.doConnect(Unknown Source) 
    

    I checked the documentation but for SocketTimeoutException it's written that "Signals that a timeout has occurred on a socket read or accept", but this is not the situation in my case. Because I am getting it during connection establishment.

    What is the difference between between these two exceptions? Actually I was expecting getting the ConnectException in any connection problem (firewall, port down, etc.)

    • Raj
      Raj
      @EJP Yes, I agree but my point was about this "Signals that a timeout has occurred on a socket read or accept." but this is not the situtaion in my case." And I was trying to convey If you are trying to connect than you fall in one category. In this case not read but accept.
  • cacert
    cacert about 10 years
    Both of these errors happening on the client side when client tries to connect to the server.No accept or read operation on my side. Check stack trace please.
  • Pphoenix
    Pphoenix about 10 years
    @cacert: When using a socket with a timeout and the server does not respond to any of your packets within the timeout, it will throw the sockettimeoutexception. You don't have to explicitly call read or accept, but it can also happen during TCP handshake. If there is a timeout during handshake (or initialization of socket), the exception is thrown in java.net.PlainSocketImpl.socketConnect(Native Method) :)
  • cacert
    cacert about 10 years
    That means if I dont set a connect timeout on the client socket, then I will get ConnectException ?
  • Pphoenix
    Pphoenix about 10 years
    @cacert: Yes, probably :) I am not 100% sure of how Socket is implemented, but that should be the logical way. EDIT: socketConnect() calls a native method, so that will probably depend on underlying C-implementation.
  • cacert
    cacert about 10 years
    Interesting fact. I checked and it works that way. Then can I have one more question..If I need to know I get connect or read timeout, how can I understand I get which one.. I get the same exception with different message as far as I see.
  • user207421
    user207421 about 10 years
    @cacert Why? You know whether you were doing a connect() or a read(). The situation isn't ambiguous.
  • cacert
    cacert about 10 years
    So if I get SocketTimeoutException how can I understand if I get it during communication (during read) or I could not connect to the server.
  • Raj
    Raj about 10 years
    @cacert You will get java.net.SocketTimeoutException: Read timed out during communication.
  • Pphoenix
    Pphoenix about 10 years
    @cacert: You can see in which method the exception was thrown. If it was in socketConnect it is a connection problem, if it is accept or read it is timeout
  • user207421
    user207421 almost 10 years
    Connect timeouts aren't caused by the peer being inactive, they are caused by the peer host being inactive or contra it a firewall rule; and if the peer is active it can't refuse the connection.

Related