我需要心跳来保持 TCP 连接打开吗?
Posted
技术标签:
【中文标题】我需要心跳来保持 TCP 连接打开吗?【英文标题】:Do I need to heartbeat to keep a TCP connection open? 【发布时间】:2010-10-26 08:15:42 【问题描述】:我有两个通过 TCP/IP 进行通信的组件。组件 A 充当服务器/侦听器,组件 B 是客户端。两人应该尽快沟通。任何时候都只能有一个连接(尽管这个问题除外)。我公司的一位高级开发人员说我需要在两个组件之间使用应用程序级心跳来确保连接保持打开状态。
我认为 TCP/IP 的连接保持打开状态,但我阅读了许多博客/网站,说在这些应用程序之间进行心跳是非常标准的做法。
我知道组件 A 检测组件 B 的部分原因,因此如果组件 B 存在通信问题(链接已关闭或组件 B 未运行),它可以通知支持人员。是否出于任何其他原因需要心跳?例如确保经常有“管道中”的东西保持开放?
组件 A 当前每 20 秒对组件 B 进行一次心跳,如果在 120 秒内没有从组件 B 收到任何返回,则关闭连接。然后它继续侦听连接,假设组件 B 将在链接断开时定期尝试重新连接。这成功了。
重申我的问题:是否需要心跳来保持 TCP/IP 连接处于活动状态?
【问题讨论】:
这种行为是否也取决于实现?这是 TCP 标准中指定的内容,还是保留为实现细节?希望其他人也能回答这个问题。 我会说这是一个实现细节,因为并非所有基于 TCP/IP 的协议都实现它完全取决于您。 是的 - 不是因为 TCP/IP - 但由于其他硬件或软件的原因,您的连接可能会通过防火墙和家庭“路由器”,它们往往会丢弃不活动的 TCP 连接,相关:***.com/questions/3907537/… 【参考方案1】:不管怎样,连接应该保持打开状态,但是通常会看到协议实现心跳以帮助检测死连接,例如使用 PING 命令的 IRC。
【讨论】:
keepalives 的另一个常见原因是通过 nat 网关保持连接打开。虽然 TCP 本身不需要保持连接来运行,但 nat 网关通常会在给定超时后“丢弃”一个 tcp 连接。 什么是正常超时?秒、分、小时? @Lloyd 我“认为”MiniGod 的意思是,“正常超时需要多长时间?” (答案以秒、分钟、小时……) @JeromeJ 谁知道,已经好几年了;) 此外,如果您的连接是通过代理进行的,那么如果您的连接被认为是陈旧的,您可以预期您的连接会被丢弃。不过,我认为在这种情况下保持活动不会有帮助,因为 tcp 的这一方面不会传播到应用程序。【参考方案2】:在尝试设置超时时,所谓的心跳很有用。您的插座可能看起来是打开的,但另一端的人可能正在遭受蓝屏死机。检测失效客户端/服务器的最简单方法之一是设置超时并确保每隔一段时间收到一条消息。
有些人称他们为 NOOP(No Ops)。
但是不,它们不是保持连接活动所必需的,只是有助于了解状态是什么。
【讨论】:
【参考方案3】:连接将保持打开状态 - 无需实现心跳,大多数使用套接字的应用程序都不会这样做。
【讨论】:
【参考方案4】:是否需要心跳来保持 TCP/IP 连接处于活动状态?
它们对于检测连接何时断开很有用。
【讨论】:
【参考方案5】:您不需要自己发送心跳。无论使用情况如何,TCP 连接都将保持打开状态。
请注意,TCP 实现了一个可选的keepalive 机制,该机制可用于及时识别关闭的连接,而不是要求您稍后发送数据,然后才发现连接已关闭。
【讨论】:
如何在 linux 上工作?它实际上有效吗?我可以将超时时间设置为少于 2 小时吗?例如 30 秒? 为此,应用程序需要支持keepalive。仅在 Linux 中启用它是不够的。【参考方案6】:许多协议都实现了 Lloyd 所说的心跳或健康状态类型的东西。只是为了让您知道连接仍处于打开状态,如果您可能遗漏了什么
【讨论】:
【参考方案7】:我想说,如果你没有心跳,那么你的 TCP/IP 连接是否打开都没关系。
【讨论】:
【参考方案8】:心跳不是 TCP 协议的必需品。它的实现是用来检测对方是否以非标准方式终止了连接(即没有经历拆除过程)。
【讨论】:
【参考方案9】:TCP 将使连接保持活动状态。应用程序检测信号用于应用程序级别的考虑,例如故障转移、负载平衡或提醒管理员注意潜在问题。
【讨论】:
【参考方案10】:正如许多其他人所指出的,如果留给自己的设备,TCP 连接将保持正常。但是,如果您在连接中间有一个设备跟踪其状态(例如防火墙),您可能需要保持连接以防止状态表条目过期。
【讨论】:
TCP 连接会说永远活着?【参考方案11】:TCP/IP 作为协议被指定为在您发送关闭数据包之前不会关闭。即使在无线或互联网连接参差不齐之后,我的套接字仍保持打开状态。
然而,这一切都非常依赖于实现。很可能会有一个“超时”,这意味着在考虑连接“死”之前等待响应的最长时间。有时这基于应用程序本身,有时基于 NAT 路由器。
因此,我强烈建议您保持“心跳”以检测不良连接并保持打开状态。
【讨论】:
【参考方案12】:心跳是告诉服务器你还活着的好方法,我的意思是,如果服务器正在使用 DoS 攻击预防系统,它(服务器)可能会在之后删除为该特定连接分配的所有资源它检测到在指定时间段内处于非活动状态。 他们没有授权实施任何心跳机制。
但是,如果您正在设计一个应用程序,它的主要标准是响应能力,这很好。您不希望在连接设置、DNS 查找和路径发现上浪费时间。只是一直保持连接,不断发送心跳,应用程序知道连接是活动的,不需要连接设置。只是简单的发送和接收。
【讨论】:
【参考方案13】:如果您使用 Windows,请注意 TCP Keep-alive。默认情况下,除非您使用 Windows 注册表或通过 setsockopt 全局打开它,否则它会被禁用。
默认保持活动间隔为 2 小时。
http://msdn.microsoft.com/en-us/library/ms819735.aspx
如果不希望 2 小时保持活动状态,您可能需要实现自己的心跳并在 Windows 上禁用 TCP 保持活动状态。
【讨论】:
Keep alive 可以实现为一个套接字选项SO_KEEPALIVE 用于单个连接。消息之间的间隔默认为 1 秒。这可能需要两个端点的支持才能正确操作。【参考方案14】:基本上,TCP 连接会创建存储在交换机中的链接状态以进行路由。为了检测断开的连接(例如当一个对应方崩溃(没有发送适当的断开连接)时),这些状态必须在一段时间不活动后被驱逐。发生这种情况时,您的 TCP 连接已关闭。 虽然我无法准确判断这些超时时间有多长,但它们似乎取决于设备生产商和/或互联网提供商。我记得我的空闲 SSH 终端会话被我以前的 1 和 1 互联网提供商迅速关闭(不到 15 分钟的空闲时间),而他们在使用 Kabel-BW 提供的连接时保持打开几个小时......
最后,我以我之前的演讲者结束:心跳是判断连接是否仍然存在和启动的好方法......
【讨论】:
【参考方案15】:如果您的组件:
在传统的有线网络中 它们之间没有防火墙或 NAT 路由器 它们都没有崩溃那么你就不需要心跳了。
如果这些假设中的任何一个是错误的(我在看着你,GPRS!),那么很快就需要检测信号。
【讨论】:
不过,这通常是网络。考虑一下 Peter Deutsch 的分布式计算谬误;我们知道网络本质上是不可靠的,因此应将其视为应用程序中几乎确定的故障点。在这种情况下,无论是否使用传统的有线网络,都假设您在某个时候会遇到故障,并设计您的应用程序来处理这种情况。【参考方案16】:TCP 不需要保持活动消息来保持会话打开。该协议旨在用于可以每隔几周激活一次而不会出现问题的终端和打印机。
其他答案确定的透明网络级元素肯定会造成令人难以置信的破坏,当它们行为不端并失去会话或以其他方式干扰流量时会杀死整个工厂。这总是不正确的,不应要求应用程序或操作系统开发人员采取任何行动。
如果没有保持连接,则只有在下次尝试传输时才会检测到通信丢失错误。
有三种可能的保活级别:
-
套接字级别使用操作系统设置或SO_KEEPALIVE 选项保持活动状态。这是透明的,并且会及时检测到通信错误或损坏的合作伙伴系统。
从应用程序发送零长度帧通常会提供类似的结果。这将强制一个 TCP PUSH 和 ACK 分段对来检测丢失的会话。
发送和接收的应用程序级别保持活动消息用于轮询合作伙伴以获取活动响应。
一方定期发送心跳消息。
前两个不会导致通过通道传输的应用程序级信息发生变化,尽管它们必然会触发空段的传输。
最后两个选项导致应用程序通信并且可以提供更多信息。例如,如果主机应用程序已经停止并且不会响应,那么前两个备选方案无法检测到这种故障模式。第四个选项隐式起作用。发送者最终会收到一个错误,而接收者应该期待周期性的消息作为健康会话的指示。
如果使用更高级别的协议 - 例如 RPC 或 REST,则返回良性内容的 Ping() 函数可能会有所帮助。
除非必须检测连接故障,否则在必要时简单地重新连接通常更容易。选择取决于应用程序级协议和需求中的端到端消息保证。
【讨论】:
以上是关于我需要心跳来保持 TCP 连接打开吗?的主要内容,如果未能解决你的问题,请参考以下文章