java.net.SocketTimeoutException vs java.net.ConnectException

前端 未结 4 859
暗喜
暗喜 2021-01-04 20:07

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

Caused by: java.net.SocketTimeoutException: con         


        
4条回答
  •  隐瞒了意图╮
    2021-01-04 21:03

    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.

提交回复
热议问题