【问题标题】:Keep Alive TCP/IP connected sockets over the Internet - when? how? and how much?通过 Internet 保持活动 TCP/IP 连接的套接字 - 什么时候?如何?多少钱?
【发布时间】:2011-04-23 21:07:27
【问题描述】:

更新:如果您想省去冗长的序言,请跳至答案。

TCP/IP 连接 KeepAlive 被指定为至少每两个小时一次:https://www.rfc-editor.org/rfc/rfc1122#page-101。问题是这是在 1989 年编写的,并且担心发送额外的 KeepAlive 数据包的成本!然而,它仍然是大多数操作系统根据规范在一段时间不活动后通过连接的套接字发送 KeepAlives 的默认时间!当然,现在大多数连接在此之前超时,如果不活动,并且如果通过 Internet 连接到对等点,那么在您不知情的情况下,连接就会在此之前死掉(尽管设置的超时高于此值 - 我怀疑是因为中间的路由器表不会打扰保留它还活着 - 我一直想知道泄露的最后一条消息去了哪里... 更新: 原因是可能在您或远程主机端的“路由器”是“有状态的”并且可以感知连接并且在一段时间不活动后断开连接-您通过Internet经过的路由器无法断开您的连接-他们不在乎-数据包只是发送到它必须去的地方)。因此,我看到了 2 种常见的解决方案来保持 Internet 上的连接:

  1. 忽略(编辑: 已向我指出,这并没有忽略规范,它只是更改了默认值)规范并将系统范围内的 KeepAlive 间隔更改为低于 2 小时,或者2) 实施您自己的“KeepAlive”系统,定期轮询对等方。

不管怎样;什么是合适的(发送 KeepAlive 的不活动时间)?我已经看到了从 1 秒到默认 2 小时的所有内容。似乎这个数字已经被吸走了......如果我有一个可能从世界任何地方连接的客户端应用程序,那么什么是安全和合理的时期(我想要一个单一的持久连接)?通过互联网连接到世界另一端的许多跳远的对等点,连接在 301 秒后终止(尽管您只有在尝试发送某些内容时才知道)所以将周期设置为 300 秒似乎是一个神奇的数字 -我在死亡前 1 秒获得了 KeepAlive - 这个间隔从来没有让我失望过……但它安全吗?

编辑:这个特殊的连接是在 C# 3.0 中实现的,所以欢迎使用代码。

【问题讨论】:

  • 大多数与 TCP 相关的超时是 90 秒,所以我会每 60 秒发送一次保活
  • 谢谢,但我需要的不仅仅是这些 - 你有任何例子吗?在我的情况下,5 分钟(300 秒)似乎很好,我很难想象什么时候需要少于这个时间(因为我连接到世界的另一端),也许是拨号 - 在这种情况下我需要让 KeepAlive 有更多时间在发送后到达对等方...
  • 我想很清楚,路由器不持有 TCP 连接,它不关心,它对任何连接都没有状态。纯路由功能仅查看 IP 标头(第 3 层)以查看数据包的去向,并且它的路由表是预先计算的。包括 NAT(包括在家庭“路由器”上)和防火墙在内的全状态节点可能会感知连接,并且每个节点都有自己的超时。在几乎任何网络上,保持活动的流量都很小。但是,不要在移动网络上将此设置得太低,因为它会浪费大量资源。
  • 谢谢,这清楚了很多-这将其范围缩小到我的设备必须比外部连接保持不活动的本地连接更长的时间-这解释了为什么在他们的客户端部署到外部之前不会遇到这些问题..如果您将其放入答案中,我可以将其标记为答案.. 谢谢!
  • @Kevin:你也知道家庭用户有状态的节点通常会在多长时间后断开 TCP 连接?

标签: c# sockets tcp


【解决方案1】:

何时

当你想防止你的连接被断开时。

如何

通过发送 TCP/IP KeepAlives 或自己发送一些东西可能在一段时间不活动后发送一些东西(推荐因为设置发送 TCP/IP KeepAlives 的时间段将在系统级别应用于所有连接的套接字,而不是在应用程序级别)。

多少

一根绳子有多长?首先,您必须了解连接断开的原因:

连接断开的原因是:

家庭/商业“路由器”和“有状态”和连接感知的防火墙往往会在一段时间不活动后断开外部 TCP 连接

所以它与您的应用程序或 TCP/IP 本身无关,而是与您的连接通过的硬件或软件有关。您可以对家庭/商业设备/软件可能会断开连接的典型不活动期进行一些研究(请参见下面的列表)。但是,如果对等点可能是 Internet 上的任何用户:

最终,如果您不知道他们通过什么设备/软件:允许客户端设置自己的不活动期(在此期间发送一些东西以保持连接活跃)。

以短时间间隔(不活动)发送 KeepAlives(或您的等价物)以适应所有情况(尽管不必要的流量是一件坏事,现在每隔几秒不活动就会有一个额外的数据包下降海洋,除了移动网络仍然)。但请注意,根据 TCP/IP 规范,它应该能够在临时中断中幸存,因此将其设置得太低可能会产生无法在临时中断中幸存的不良影响,来自 http://aplawrence.com/Bofcusm/2426.html

收紧 keepalive 参数的缺点是你还 严重限制了 TCP 在电缆中断时的恢复能力。一个会话 其两端都处于活动状态并准备好正常运行,即使 中间电缆或路由器断开了几分钟。如果 你告诉服务器疯狂地发送keepalives,它会注意到一个 否则会继续存在的电缆断开和断开连接的会话 很好。

但是,如果您无论如何都在进行一些通信,那么您将遇到中断,因此您必须处理这个问题,我认为这种担忧已经过时,因为今天不会出现临时中断(它们更有可能是永久性的 - 电缆拔出)持久连接(与狡猾的拨号相反)。如果出现中断,您可能需要重新建立连接(例如 RDP)或不重新建立连接(例如 Telnet)。

对常见应用程序使用的一些研究:

App    |    KeepAlive sent after    |    configurable    | ref
--------------------------------------------------------------
Telnet |    600 seconds             |          Y         | http://www-01.ibm.com/support/docview.wss?uid=nas14adccb91a24d9ed28625694900513857
MS RDP |    ?

还有一些关于哪些设备/软件会断开非活动连接以及何时断开的研究:

Device/SW                |    dropped after    |    configurable    | ref
--------------------------------------------------------------
Windows 2003 Firewall    |    24 hours         |          ?         | http://technet.microsoft.com/en-us/library/cc755604(WS.10).aspx
SonicWall TZ100/200      |     5 mins          |          Y         |  http://www.sonicwall.com/downloads/SonicWALL_TZ_100_200_Series_Getting_Started_Guide.pdf
Netgear FR114P           |     5 mins          |          N         | http://www.broadbandreports.com/forum/remark,4182300
Cisco ASA                |     1 hour          |          Y         | http://www.cisco.com/c/en/us/td/docs/security/asa/asa91/configuration/firewall/asa_91_firewall_config/conns_connlimits.html

为了所有人的利益,请编辑/完善这些列表。

【讨论】:

  • 将您自己的答案标记为正确? “我认为这种担忧已经过时,因为不会出现临时中断”是完全不正确的。将电缆从路由器中拉出并插入其他地方怎么样?沼泽标准用例。
  • 这违反了 stackoverflow.com 协议。如果您有评论,请添加评论。根据定义,提出问题的人不知道答案,所以不是提供答案的人。
  • :) 我后来找到了正确的答案(特别是来自 Kevin Nesbits cmets),为了大家的利益,我在这里添加了它。告诉我我违反的协议部分:)
  • @EJP 哈哈,谢谢你的徽章——没有你我做不到!
【解决方案2】:

TCP/IP 连接 KeepAlive 是 指定最多每两个 小时。

这不是它所说的。它说“此时间间隔必须是可配置的,并且必须默认为不少于两个小时。”

问题是这是写在 1989年,担心成本 发送额外的 KeepAlive 数据包!

让keep-alive可选并且如果提供2小时默认值的真正原因是该列表中的#(2) - TCP/IP应该能够承受中间设备的临时中断、重新路由等。这是一个有用的机制,例如Telnet 服务器以检测丢失的客户端。

无视规范并更改您的 系统范围的 KeepAlive 间隔到 不到 2 小时。

这不是“无视规范”。这只是更改默认值。

大多数需要长期连接的应用程序要么在自己的应用程序协议中提供 ping,要么使用连接池以在连接失败时幸免于难。

【讨论】:

  • 感谢您的澄清 - 但您仍然没有回答我的问题 - 什么是发送 KeepAlives 的合适的不活动期?目的是:“TCP/IP 应该能够承受中间设备的临时中断、重新路由等。当通过 Internet 连接时,它是一种有用的机制,例如 Telnet 服务器检测丢失的客户端”......
  • 我半开玩笑地说原因是发送额外数据包的成本(这是原因之一) - 我知道主要原因 - 这正是我想要使用它的目的!
  • 完全取决于您的应用程序。很明显,TCP/IP 的设计者觉得两个小时太短了。但是,如果您有一个应用程序需要每 10 秒对等点出现一次,那么 5 秒可能是一个好时机。或者 20。如果您的时间段以分钟为单位,我会使用读取超时和连接池而不是 ping。
  • 无意义的咆哮。何时、如何以及多少什么? 答案取决于应用程序。您已经定性地描述了您的应用程序,但没有定量地描述您的应用程序,并且您正在提出定量问题。除了你,没有人可以回答他们。它的响应时间要求是什么?它多久使用一次连接?它可以容忍多少停机时间?也许 Telnet 默认值足以满足您的应用程序。也许不是。我不知道。我也越来越不在乎了。
  • 这取决于使用的应用程序!我会假设连接关闭不是因为底层套接字被关闭,而是因为服务器应用程序决定是时候关闭连接了。我不会更改默认的保持活动状态,但正如已经指出的那样,在应用程序协议中实现保持活动状态——这就是要走的路!
猜你喜欢
  • 2020-12-20
  • 2015-10-17
  • 2020-01-12
  • 1970-01-01
  • 2021-12-26
  • 2014-02-08
  • 1970-01-01
  • 2015-03-05
  • 2016-10-24
相关资源
最近更新 更多