SocketTimeoutException

SocketTimeoutException

当使用Java客户端套接字连接到服务器时,我有这两个不同的连接超时异常。

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)

我检查了文档,但是对于SocketTimeoutException,它写为“套接字读或接受时发生超时的信号”,但是我的情况并非如此。因为我在建立连接的过程中得到了它。

这两个异常(exception)之间有什么区别?实际上,我期望在任何连接问题(防火墙,端口断开等)中获取ConnectException

最佳答案

也来到这里寻找相同的答案,貌似the docs容易被误解:



我在此忽略的关键部分是“错误” ...转到the source,我可以看到Java的connect()实际上是如何调用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
}

即我认为当网络速度慢或主机完全不响应时会抛出SocketTimeoutException。检查man connect,我看到当“没有人在远程地址上监听”时,即ICMP告诉我们,必须抛出ECCONNREFUSED

这意味着,如果像我一样,您尝试使用timeout连接到尚未准备好连接到的(localhost)套接字,那么您就可以使用SOL。

10-04 17:09