java.net.SocketTimeoutException vs java.net.ConnectException [英] java.net.SocketTimeoutException vs java.net.ConnectException

查看:640
本文介绍了java.net.SocketTimeoutException vs java.net.ConnectException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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) 

我检查了文档但是对于 SocketTimeoutException 它写的是信号在套接字读取或接受时发生超时,但这不是我的情况。因为我在连接建立期间得到它。

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.

这两个例外有什么区别?实际上我期待在任何连接问题(防火墙,端口关闭等)中获得 ConnectException

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

推荐答案

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

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.

我忽略的关键部分是错误...转到我可以看到Java的 connect()实际上是如何调用Linux connect()

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
}

即。我认为当网络速度很慢或者主机根本没有响应时,会抛出 SocketTimeoutException 。检查 man connect ,我可以看到没有人在远程地址上侦听时必须抛出 ECCONNREFUSED ,即ICMP告诉我们。

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.

这意味着如果像我一样,你试图使用超时要连接到未准备好连接的(localhost)套接字,你就是SOL'd。

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.

这篇关于java.net.SocketTimeoutException vs java.net.ConnectException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆