当使用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。