java 套接字连接超时:规范在哪里?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13266403/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Socket connect timeouts: where is the specification?
提问by Aubin
The context of my work is my local area network.
我的工作环境是我的局域网。
The code samples below are written in Java language but my question is about TCP, not programming.
下面的代码示例是用 Java 语言编写的,但我的问题是关于 TCP,而不是编程。
I have experienced the following connection timeout:
我遇到过以下连接超时:
- 2 ms when connection established
- 1 005 ms when host is alive but not listen on the specified socket port
- 21 000 ms when host is down
- 建立连接时为 2 毫秒
- 1 005 ms 当主机处于活动状态但未侦听指定的套接字端口时
- 主机关闭时为 21 000 毫秒
This values comes from observation of my network but I presume it exists a RFC.
这个值来自对我的网络的观察,但我认为它存在一个 RFC。
Here is some information about timeout:
以下是有关超时的一些信息:
- RFC 1122
- RFC 793
- Nagle's_algorithmand TCP_NO_DELAY
- RFC 1122
- RFC 793
- Nagle's_algorithm和 TCP_NO_DELAY
Can you give me more pointers?
你能给我更多的指点吗?
@Override
public void run() {
for( int port = _portFirst; port < _portLast; ++port ) {
String host = "192.168.1." + _address;
boolean success = false;
long before = System.currentTimeMillis();
try {
Socket socket = new Socket();
SocketAddress endpoint = new InetSocketAddress( host, port );
socket.connect( endpoint, 0 );
success = true;
socket.close();
}// try
catch( ConnectException c ){/**/}
catch( Throwable t ){
t.printStackTrace();
}
long duration = System.currentTimeMillis() - before;
System.err.println( host + ":" + port + " = " + duration );
_listener.hostPinged( host, port, success, duration );
}
}
回答by user207421
There is no RFC for connection timeouts. It is impossible for any RFC or other document to know the conditions prevailing in any network in advance.
没有关于连接超时的 RFC。任何 RFC 或其他文件都不可能提前知道任何网络中普遍存在的情况。
In general you can expect a successful connection to be very quick; an ECONNREFUSED
(ConnectException: connection refused
) to be about as quick; and a connection timeout (ConnectException: connect timeout
) to take as long as it takes, depending on the cause, the platforms at both ends, and the nature of the intervening network. In Windows I believe a connection timeout consists of the total time across three connection attempts with timeouts 6s, 12s, and 24s, total 42s; in various Unixes I believe the total is more like 70s, which could result from 3 attempts with timeouts 10s, 20s, and 40s. As you see it is up to the platform. There is also the issue that filling the backlog queue at a Windows server will cause RSTs to be issued to incoming SYNs, where on a Unix/Linux server it will cause no response at all to incoming SYNs.
通常,您可以期望非常快地成功连接;一个ECONNREFUSED
( ConnectException: connection refused
) 大约一样快;以及连接超时 ( ConnectException: connect timeout
) 所需的时间,具体取决于原因、两端的平台以及介入网络的性质。在 Windows 中,我认为连接超时包括三个连接尝试的总时间,超时时间分别为 6 秒、12 秒和 24 秒,总共 42 秒;在各种 Unix 中,我相信总数更像是 70 秒,这可能是由于 3 次尝试超时 10 秒、20 秒和 40 秒造成的。如您所见,这取决于平台。还有一个问题是,在 Windows 服务器上填充积压队列会导致向传入的 SYN 发出 RST,而在 Unix/Linux 服务器上,它将导致对传入的 SYN 根本没有响应。
You should also note that in Java, and contrary to many years of Javadoc:
您还应该注意到在 Java 中,与多年的 Javadoc 相反:
A zero connect timeout does not imply an infinite timeout, it implies the platform default timeout, which as shown above isn't above about 70s;
You cannot specify a connection timeout that increases the platform default; you can only use it to decrease the platform default.
零连接超时并不意味着无限超时,它意味着平台默认超时,如上所示不超过约 70 秒;
您不能指定增加平台默认值的连接超时;您只能使用它来减少平台默认值。
回答by Anders R. Bystrup
As you have found out, you can specify a timeout in the connect(...)
method call as such:
正如您所发现的,您可以在connect(...)
方法调用中指定一个超时时间:
connect( SocketAddress endpoint , int timeout )
And remember that "...A timeout of zero is interpreted as an infinite timeout."(where "infinite" often really means "use the OS default").
并记住“...超时为零被解释为无限超时。” (其中“无限”通常真的意味着“使用操作系统默认值”)。
As for the defaults, they are OS dependent, but usually fairly consistent anyways. If you're on a linux box, have a look at /proc/sys/net/ipv4/tcp_keepalive*
(but don't change them unless you know what you're doing :-)
至于默认值,它们依赖于操作系统,但通常还是相当一致的。如果您使用的是 linux 机器,请查看/proc/sys/net/ipv4/tcp_keepalive*
(但不要更改它们,除非您知道自己在做什么:-)
Cheers,
干杯,