套接字连接超时:规范在哪里?

时间:2012-11-07 09:08:35

标签: java sockets networking tcp

我工作的背景是我的局域网。

下面的代码示例是用Java语言编写的,但我的问题是TCP,而不是编程。

我遇到了以下连接超时:

    建立连接时
  • 2 ms
  • 主机处于活动状态但没有侦听指定的套接字端口时的1 005 ms
  • 主机关闭时
  • 21 000 ms

这个值来自我的网络观察,但我认为它存在一个RFC。

以下是有关超时的一些信息:

你能给我更多指示吗?

@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 );
   }
}

2 个答案:

答案 0 :(得分:13)

连接超时没有RFC。任何RFC或其他文档都不可能事先知道任何网络中的主要条件。

一般来说,您可以期待成功的连接非常快;一个ECONNREFUSEDConnectException: connection refused)快要快;和连接超时(ConnectException: connect timeout),只要它需要,取决于原因,两端的平台,以及介入网络的性质。在Windows中,我认为连接超时包括三次连接尝试的总时间,超时为6s,12s和24s,总共42s;在各种Unix中,我认为总数更像是70s,这可能是因为3次尝试超时10s,20s和40s。如您所见,这取决于平台。还有一个问题是,在Windows服务器上填充积压队列将导致RST被发送到传入的SYN,在Unix / Linux服务器上,它将不会对传入的SYN产生任何响应。

你应该注意到在Java中,与Javadoc的多年相反:

  1. 零连接超时并不意味着无限超时,它意味着平台默认超时,如上所示不超过70秒;

  2. 您无法指定增加平台默认值的连接超时;您只能用它来降低平台默认值。

答案 1 :(得分:1)

如您所知,您可以在connect(...)方法调用中指定超时:

connect( SocketAddress endpoint , int timeout )

请记住"...A timeout of zero is interpreted as an infinite timeout."(其中“无限”通常的意思是“使用操作系统默认值”)。

至于默认值,它们取决于操作系统,但通常相当一致。如果你在Linux机器上,请查看/proc/sys/net/ipv4/tcp_keepalive*(但除非你知道你在做什么,否则不要改变它们: - )

干杯,