【问题标题】:Socket connect timeouts: where is the specification?套接字连接超时:规范在哪里?
【发布时间】:2012-11-07 09:08:35
【问题描述】:

我的工作环境是我的局域网。

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

我遇到了以下连接超时:

  •  2 ms when connection established
    
  • 1 005 毫秒,当主机处于活动状态但未侦听指定套接字端口时
  • 主机关闭时为 21 000 毫秒

这些值来自对我的网络的观察,但我认为它存在一个 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 );
   }
}

【问题讨论】:

  • 这些超时由您的操作系统控制,您拥有哪个操作系统/版本?
  • BTW端口扫描可以通过nmap等现有工具轻松完成,如果可以的话我会考虑使用它。
  • 谢谢,我知道nmap、lookatlan.comoverlooksoft.com,但我的目标是获得基础知识

标签: java sockets networking tcp


【解决方案1】:

没有关于连接超时的 RFC。任何 RFC 或其他文档都不可能提前知道任何网络中的普遍情况。

一般而言,您可以期望成功连接非常快; ECONNREFUSED (ConnectException: connection refused) 也差不多;以及连接超时 (ConnectException: connect timeout),根据原因、两端的平台以及介入网络的性质,需要尽可能长的时间。在 Windows 中,我相信连接超时包括三个连接尝试的总时间,超时时间分别为 6 秒、12 秒和 24 秒,总共 42 秒;在各种 Unix 中,我相信总数更像是 70 秒,这可能是由于 3 次尝试超时 10 秒、20 秒和 40 秒造成的。如您所见,这取决于平台。还有一个问题是,在 Windows 服务器上填充积压队列会导致向传入的 SYN 发出 RST,而在 Unix/Linux 服务器上,这将导致对传入的 SYN 完全没有响应。

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

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

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

【讨论】:

  • 但是 RFC 中有时会指定超时......所以这不是“不可能的”
  • @Aubin RFC 指定超时并非不可能,但后来我没有说它是。
  • 如果我想实现 tcp longpolling 技术怎么办。我能以某种方式超过这个最大系统超时吗?
  • @tobi 您的问题在术语上体现了矛盾。没有。
  • @EJP 好的。所以我想如果我的长轮询最多等待 60 秒左右,我是安全的。
【解决方案2】:

正如您所发现的,您可以在 connect(...) 方法调用中指定超时,如下所示:

connect( SocketAddress endpoint , int timeout )

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

至于默认值,它们取决于操作系统,但通常还是相当一致的。如果您使用的是 linux 机器,请查看 /proc/sys/net/ipv4/tcp_keepalive*(但除非您知道自己在做什么,否则不要更改它们 :-)

干杯,

【讨论】:

  • 然而,不管 Javadoc 是什么,零连接超时不是实际上“解释为无限超时”。试试看。
  • /proc/sys/net/ipv4/tcp_keepalive* 与连接超时无关。
  • 我个人现在面临一个问题,尽管在我的连接调用中设置了很长的超时,但我仍然收到超时。它不尊重我假设的值,因为它比我指定的超时更早达到超时?这怎么可能?
  • @buddyp450 查看我的回答。当您发布该评论时,它已经存在六年了。
猜你喜欢
  • 2011-05-11
  • 1970-01-01
  • 1970-01-01
  • 2012-11-17
  • 2011-02-05
  • 2018-11-26
  • 2020-06-02
  • 2016-10-02
相关资源
最近更新 更多