java.net.SocketTimeoutException vs java.net.ConnectException [英] 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屋!