通过Internet保持活动的TCP/IP连接套接字 - 什么时候?怎么样?多少钱?

mar*_*mnl 11 c# sockets tcp

更新:如果你想节省冗长的序言,请跳至答案.

TCP/IP连接KeepAlives指定为每两个小时至少一次:http://tools.ietf.org/html/rfc1122#page-101.问题是这是写于1989年,并担心发送额外的KeepAlive数据包的成本!然而,仍然是默认时间,大多数操作系统根据规范在一段时间不活动后将KeepAlives发送到连接的套接字!当然,现在大多数连接超时之前的方式如果不活动,如果通过Internet连接连接到对等设备之前没有你的知识方式(尽管设置的超时高于那个 - 我怀疑因为中间的路由器表不打扰保持它活着 - 我总是想知道泄露的最后一条消息在哪里... 更新:原因是可能位于您或远程主机端的"路由器"处于"有状态"且可识别连接并在一段时间不活动后断开连接 - 您通过Internet访问的路由器无法断开连接 - 他们不关心 - 数据包只是发送到必须去的地方).所以我看到了两种常见的解决方案来保持互联网上的连接:

1)忽略(编辑:已经向我指出这不是无视规范它只是改变默认值)规范并将系统范围的KeepAlive间隔改为低于2小时,或2)实现自己的'KeepAlive'系统定期轮询对等体.

无论哪种方式; 什么是合适的时间段(发送KeepAlive的不活动时间)?我已经看到从1秒到默认2小时的所有内容.似乎这个数字是从拇指中吸出的......如果我有一个客户端应用程序从世界上任何地方连接什么是安全合理的时期(我想要一个持久的连接)?通过互联网连接到世界另一端的同伴很多跳,连接在301秒后死亡(尽管你在尝试发送东西时只知道它)所以将周期设置为300秒似乎是神奇的数字 - 我在死亡前获得了KeepAlive 1秒钟 - 这段时间从来没有让我失望过..但是它安全吗?

编辑:这个特殊的连接我实现在C#3.0所以代码在欢迎.

mar*_*mnl 14

什么时候

当您想要阻止连接被删除时.

怎么样

通过发送TCP/IP KeepAlives或自己发送内容(通过设置发送TCP/IP KeepAlive的时间段后建议将在系统级别应用于所有连接的套接字而不是应用程序级别),通过发送一些不活动后的内容).

多少

一段绳子有多长?首先,您必须了解连接被删除的原因:

连接断开的原因是:

家庭/商业"路由器"和"有状态"和连接感知的防火墙倾向于在一段时间不活动后丢弃外部TCP连接

因此,有没有与你的应用程序或TCP/IP本身,而是用做硬件或软件的连接经过.您可以对典型的不活动时段进行一些研究,在此期间,您可能经历的家庭/商业设备/软件断开连接(请参阅下面的列表).但是,如果对等方可能是Internet上的任何用户:

最终,如果你不知道他们经历了什么设备/软件:允许客户设置他们自己的不活动时间(发送一些东西以保持连接活着).

或者以短暂的间隔(不活动)发送KeepAlives(或等效物)以适应所有情况(尽管不必要的流量是一件坏事,现在每隔几秒不活动的额外数据包是海洋中的一滴,除了移动网络仍然如此).但是根据TCP/IP的规范警告它应该能够在临时停机中存活下来,因此将其设置得太低可能会导致不能幸免于临时中断的不良影响,来自http://aplawrence.com/Bofcusm/2426.html:

收紧保持活动参数的另一个缺点是,在面对电缆断电时,您还会严格限制TCP的弹性.即使中间电缆或路由器断开连接几分钟,其两端都处于活动状态且准备好正常运行的会话仍保持活动状态.如果您已经告诉服务器疯狂地发送Keepalive,它会发现电缆断开并断开会话,否则这些会话可以很好地存活.

但是,如果你正在做一些通信,那么你将不得不处理这个问题,因为你不得不处理这个问题,我认为这个问题已经过时了,因为人们没有暂时中断(它们更可能是永久性的 - 电缆不插电)与今天的持续连接(而不是狡猾的拨号说).如果您有中断,您可能想要重新建立连接(例如RDP)或不重新建立连接(例如Telnet).

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

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

并研究了什么设备/软件丢弃不活动连接以及何时:

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
Run Code Online (Sandbox Code Playgroud)

为了所有人的利益,请编辑/优化这些列表.

  • :) 我后来找到了正确的答案(特别是来自 Kevin Nesbits 的评论),为了所有人的利益,我在这里添加它。给我看看我违反的协议部分:) (2认同)

use*_*421 10

TCP/IP连接KeepAlives最多每两个小时指定一次.

这不是它所说的.它说'这个间隔必须是可配置的,必须默认不少于两个小时.'

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

使保持活动可选的真正原因和2小时默认(如果提供的话)是#(2)在该原因列表中 - TCP/IP应该能够在中间设备的临时中断,重新路由等中存活下来.它是一个用于例如Telnet服务器检测丢失的客户端的有用机制.

忽略规范并将系统范围的KeepAlive间隔更改为低于2小时.

这不是'无视规范'.那只是改变了默认值.

大多数需要长期连接的应用程序要么在自己的应用程序协议中提供ping,要么使用连接失败后的连接池.

  • 它完全取决于你的应用程序.很明显,TCP/IP的设计者觉得两个小时太短了.但是如果你有一个应用程序需要对手每隔10秒就在那里,那么5秒钟也许是个好时机.或者20.如果您的时间段是几分钟,我将使用读取超时和连接池而不是ping. (5认同)
  • 无意义的咆哮.什么时候,如何以及多少?*答案取决于应用程序.您已经定性地描述了您的应用程序,但没有定量描述,您提出的是定量问题.没有人,但你可以回答他们.它的响应时间要求是什么?它多久使用一次连接?它可以承受多少停机时间?也许Telnet默认值足以满足您的应用需求.也许不是.我不知道.我也不在乎. (5认同)
  • 感谢您的澄清 - 但您仍然没有回答我的问题 - 什么是发送KeepAlives的合适的不活动时间?出于以下目的:"TCP/IP应该能够在中间设备的临时中断,重新路由等中存活下来.当通过Internet连接时,它是一种有用的机制,例如Telnet服务器检测丢失的客户端"... (2认同)