`
collegeyuan
  • 浏览: 30949 次
  • 性别: Icon_minigender_2
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

TCP长连接中断的实时检测

 
阅读更多

目前TCP/IP已经成为网络的主导技术。通过对TCP底层实现的分析,对TCP/IP编程中一个长期使人困惑的问题----网络连接中断的实时检测—进行深入的分析,并提出相应的解决方案。
  
  0引言
  作为现代网络的主导技术,TCP/IP编程看起来非常简单,但在经历了最初的高效率后,往往会在细节面前停滞不前,这常常是因为对TCP协议底层细节的缺乏了解所导致的。
  TCP是面向连接协议,而UDP是无连接协议,许多初学者发现可以没有任何数据流通过一个空闲的TCP连接,如果TCP连接的双方都没有向对方发送数据,则在两个TCP模块之间不交换任何信息。这意味着可以启动一个客户与服务器建立一个连接,然后离去数小时至数个星期连接依然保持。中间路由器可以崩溃和重启,电话线可以被挂断再连通,只要两端的主机没有被重启,则连接依然保持建立。
  因此,初次接触TCP/IP协议组的程序员感到很迷惑:TCP中并没有可以在其他网络协议中发现的连接阶段的轮询,甚至发现TCP不给应用程序提供既时的网络连接中断的通知。一些程序员据此断定TCP不适用于一般的应用程序到应用程序的通信。TCP为什么不提供通知呢?
  1原理分析
  TCP通常被称为可靠的协议,即“TCP保证发送数据的传输”,这通常会产生误解:TCP不会出错。事实是只要双方保持连接,TCP就能保证数据的正确传输,但是当连接中断时,就会产生问题,原因有3个:1)永久的或暂时的网络紊乱;2)对等方应用程序崩溃;3)对等方主机崩溃,当出现以上问题时,会使双方应用程序不能互相通信,而其中一个应用程序却不能立刻意识到。发送数据给对等方的应用程序可能在知道TCP在放弃重发之前才会发现连接中断,。如果应用程序没有发送数据,可能永远不会发现网络已经中断。例如应用程序可能是一个正在等待对等方发出下一个请求的服务器,因为客户端不能和服务器通信,下一个请求永远不会到达,甚至客户端的TCP放弃并撤销连接,导致客户端中断,服务器也没有意识到这一点。
  其他的通信协议如SNA和X.25,当连接中断时会给应用程序提供通知。比如简单的直接点对点专有链接复杂的任何协议都必须使用一种轮询协议来连续地测试对等方是否存在。轮询-选择协议可能会采用显式地发送“你有要发送给我的任何数据吗?”诸如此类的消息的形式,或者它们会采用后台静态帧的形式来检测虚拟线路是否仍然存在。每一个轮询消息都会消耗网络资源,而这些资源本来可以用于“有效负载”数据的传输。
  对可获得的网络带宽的消耗是TCP不提供网络中断立即通知的一个原因。因为大多数的应用程序不需要即时的通知,所以没有必要以降低带宽的代价来提供这个功能。需要以一种及时的方式知道对等方不可到达的应用程序可以实现它们自己的机制来发现网络中断,如后面介绍的那样。
  TCP/IP设计中使用的一个基本原则是终端对终端参数[Saltzerelal.1984],该参数应用到网络上时可以表述为所有的智能应当尽可能地接近连接的终端点,而网络本身应当相对没有智能。这就是为什么TCP自己处理错误控制而不是依靠网络来提供它的原因。当这个原则应用到监控对等应用程序之间的连接时,应用程序应当提供它自己需要的功能,而不是不管应用程序是否需要这个功能都由下层提供。
  TCP不提供及时连接中断通知的最重要的原因是:网络突然中断时仍可以维持通讯的能力。TCP最早是美国国防部发起的一项研究的成果,它要求提供一个遇到战争或自然灾害引起的网络中断时仍然可以维持计算机之间可靠的通信的网络协议。通常网络紊乱是暂时的,路由器也可能找到连接的另一条路径。通过允许连接的暂时中断,甚至在终端应用程序意识到中断之前TCP就已经处理好了紊乱。
  2解决方案
  2.1方案一:使用TCPKeep-alive机制
  人们希望知道连接是否中断了,因此许多TCP的具体实现提供了一个称作Keep-alive的机制用于检测死连接,但是它并不经常用于应用程序。如果应用程序启用Keep-alive机制时,TCP就会在连接已经空闲了一段时间间隔后发送一个特殊的段给对等方。如果对等方主机可到达而且对等方应用程序仍然运行,对等方TCP就会响应一个ACK应答。在这种情况下,TCP发送Keep-alive重置空闲时间为零,并且应用程序不会收到消息交换的任何通知。
  如果对等方主机可以到达但是对等方应用程序没有运行,对等方TCP就响应RST消息,发送Keep-alive消息的TCP撤销连接并返回ECONNRESET错误给应用程序。这通常是对等方主机崩溃后重起的结果,因为如果仅仅是对等方应用程序中断或崩溃了,对等方TCP可能已经发送FIN消息了。
  如果对等方主机没有响应ACK或RST消息,发送Keep-alive消息的TCP继续发送Keep-alive探询消息,直到它认为对等方不可到达或已经崩溃了。这时它就撤销连接并通知应用程序ETIMEDOUT错误,如果路由器已经返回主机或网络不可到底的ICMP消息的话,就返回EHOSTUNREACH或ENERUNREACH错误。
  通过Keep-alive机制,TCP提供了协议层面的网络中断通知功能,但这种机制有很多问题以至于很少用于应用程序。
  首先,Keep-alive并不是TCP规范中的一部分,长期以来,是否在TCP中提供Keep-alive机制一直是有争论的话题,因此,Keep-alive不是所有的TCP实现都提供,而且实现细节也有所不同。
  需要即时通知网络中断的应用程序使用Keep-alive功能的第二个问题是和时间间隔有关的。RFC1122[Braden1989]认为,如果TCP实现了Keep-alive,保活间隔必须是可配置的,但是其默认值必须不小于两个小时,之后它才能发送Keep-alive探询消息。那么因为对等方的ACK消息并不是可靠地递交,它必须在放弃连接之前重复发送探询消息。4.4BSD具体实现在撤销连接之前以75秒的时间间隔发送9个探询消息。
  这意味着BSD派生的具体实现,大约需要2小时11分钟15秒才能发现连接已经中断了。这个时间值只有在我们认识Keep-alive是用于释放被死连接占有的资源时才有意义。例如,当客户端连接到服务器而客户端主机崩溃时就有可能发生这样的连接。如果没有Keep-alive机制,服务器就会永远等待客户端的下一个请求,这是因为它永远没有接收到FIN消息。(因为基于PC系统的用户仅仅是关闭计算机和modem而不是正确地关闭应用程序,所以这种情况正越来越普遍。)
  由于2小时的时间对于实时检测几乎没有意义,因此一些具体实现允许改变一个或两个时间间隔值,但因为保活间隔时间是系统级的变量,这些值的改变影响系统上所有的TCP连接,这是Keep-alive作为一个连接监控机制没有实际使用的主要原因:默认的时间段太长了,如果改变了默认值,它们就失去了清除长时间死连接这一最初的意义。
  Keep-alive的另一个问题是它们不仅仅检测死连接,同时也撤销它们。这有可能是应用程序所希望的,但是也有可能不是应用程序所希望的。
  2.2方案二:使用heartbeat检测
  第二种方案是在应用层来实现对连接中断的检测,其基本思想是象Keep-alive一样,定时向对等方发送探针,由于是在应用层实现,可以根据应用程序灵活掌握探测时间。实际上,边界网关协议BGP就是通过定期发送Keep-alive报文给其邻站来检测TCP连接对端的链路或主机失败,两个报文之间的时间间隔建议值为30秒。这种在应用层实现的对连接中断的检测通常称为“heartbeat检测”。
  以上算法原则尽管是在TCP上讨论,但一样适用于UDP。这种方案的最大优点在于提供了最大的灵活性。
  2.3方案三:利用TCP-KEEPALIVE套接字选项
  第三种方案是使用新的POSIX1003.1g套接字选项TCP-KEEPALIVE,它允许在每一个连接的基础上指定超时时间间隔,但是它没有广泛地实现,因此应用中使用的不多。在Linuxkernel2.4之后的TCP实现中,可以这样设置socket的探针间隔:
  #ifdefTCP_KEEPALIVE
  intsecs=120;/*2minutes*/
  setsockopt(s,IPPROTO_TCP,TCP_KEEPALIVE,&secs,sizeof(secs));
  #endif
  这种方案的缺点是,由于TCP-KEEPALIVE套接字选项是比较新的POSIX特性,不是所有TCP实现都给予支持,因此存在移植性问题;同时,由于是在传输层进行探测,灵活性不如在应用层的实现。
  3总结

  综上所述,对于TCP连接中断的检测,原理上都是通过定时向对等方发送探针数据来进行检测,不同方案的区别在于实现于不同层次,应用中可以根据需要进行不同的选择,关键在于对TCP连接的原理要透彻理解。

原文地址:http://www.guigu.org/news/guiguvip/201206117802.html

分享到:
评论

相关推荐

    java建立TCP长链接

    在TCP连接建立之前,需要经过三次握手的过程,而在连接结束后,通过四次挥手断开连接。 在Java中,我们通常使用`java.net.Socket`类和`java.net.ServerSocket`类来实现TCP通信。以下是建立TCP长连接的基本步骤: 1...

    TCP长连接Socket心跳收发消息

    TCP长连接与心跳机制是确保可靠连接的关键技术,特别是对于那些需要持续通信的服务,如在线游戏、实时聊天、数据同步等。本篇文章将深入探讨TCP长连接Socket以及心跳收发消息的原理和实现方法。 首先,TCP是一种...

    怎样及时检测出非正常断开的TCP连接.DOC

    在网络通信中,TCP 连接的非正常断开是指在非优雅的方式下断开连接,例如网线故障、物理链路中断、主机断电等原因引起的连接断开。如何及时检测出这种非正常断开的 TCP 连接是非常重要的。 在 Linux 和 Windows ...

    tcp同步连接发消息心跳检测

    测试过程中,开发者可能会编写特定的程序模拟长时间无数据交换的情况,然后观察TCP连接是否能准确地通过心跳检测判断出连接状态,以及在连接异常时是否能够正确地关闭连接。 在实际应用中,心跳检测对于保持长连接...

    Go-HiMagpie网关负责TCP长连接建立心跳消费消息队列并推送等

    HiMagpie网关就是一个基于Go语言实现的系统组件,它的主要职责是管理TCP长连接、执行心跳检测以及处理消息队列的消费与推送。下面将详细解析这些知识点。 1. **TCP长连接**: - TCP(Transmission Control ...

    TCP/IPsocket长连接

    首先,我们来详细了解一下TCP连接。TCP建立连接需要经过三次握手过程,确保双方都有能力并愿意进行通信。连接建立后,数据可以双向流动。在长连接中,一旦连接建立,就会保持开放状态,直到一方主动关闭连接或因网络...

    wincc modbus tcp通讯中断问题解决方案.pdf

    在本文档中,我们将探讨如何解决使用WinCC 7.5 SP1+UDP1版本进行Modbus TCP通信时遇到的通信中断问题。此类问题对高频电源远程监控和湿电系统的运行造成了直接影响。为解决这一难题,我们需要进行详细的诊断,包括但...

    QT TCP服务端如何判断客户端已断开连接 - 北冥有鱼的博客 - CSDN博客1

    在使用QT进行TCP服务器开发时,一个常见的需求是检测客户端是否已经断开了连接。这篇文章将介绍如何在QT中实现这一功能,特别是在C++环境中。QT提供了丰富的网络编程接口,其中包括`QAbstractSocket`类,该类包含了...

    w5500TCP server解决有时连接断开问题

    当两台设备之间建立TCP连接后,Keep-Alive功能会在一段时间无数据交换时发送一个空的数据包(称为Keep-Alive probe)到对方,以确认连接是否仍然有效。如果在一定时间内未收到响应,TCP会重新发送probe,经过多次...

    Android的socket长连接(心跳检测)

    - 心跳检测是为了防止网络拥塞、连接超时或服务器故障导致的连接中断。客户端定时向服务器发送“心跳”数据包,服务器收到后回应,以此确认连接的活跃状态。 - 定时任务:可以使用`Handler`、`Runnable`和`...

    微信小程序 TCP,IP长连接 (源码).rar

    而长连接则保持连接状态,允许多次通信而不中断,这在需要频繁交互或实时性较高的场景中非常有用,例如微信小程序中的实时聊天或推送服务。 在微信小程序中,由于其自身的特性,如生命周期管理和网络请求限制,实现...

    TCP心跳包-定时连接检测

    1. **建立连接**:客户端通过socket接口创建套接字,并使用connect函数与服务器建立TCP连接。 2. **设置心跳间隔**:在客户端,可以通过修改TCP选项(如TCP_KEEPALIVE或TCP_USER_TIMEOUT)来设置心跳包的发送间隔和...

    微信小程序-fans-server的TCP,IP长连接.zip

    心跳机制是为了检测连接是否仍然活跃,防止因网络问题导致的连接中断;重连策略确保在连接断开后能够快速恢复;连接池则可以复用已建立的连接,避免频繁创建和销毁连接的资源消耗。 在实际开发中,还需要注意一些...

    微信小程序源码-TCP,IP长连接.zip

    WebSocket是一种在单个TCP连接上进行全双工通信的协议,非常适合长连接。 3. **数据传输**:连接建立后,小程序可以通过WebSocket发送和接收数据,实现双向通信。 4. **连接管理**:需要处理网络中断、重连、心跳...

    高仿TCP,IP长连接小程序源码.zip

    1. **连接建立**:源码中可能包含客户端如何初始化TCP连接,包括设置端口号、IP地址,以及处理三次握手的过程。 2. **数据传输**:学习如何封装TCP数据包,实现数据的发送和接收,以及错误检测和重传机制。 3. **...

    基于TCP的全连接端口扫描

    全连接端口扫描,也称为TCP Connect扫描,是指扫描者向目标主机的每一个端口发送SYN报文,然后完成三次握手,建立一个完整的TCP连接。如果目标主机的端口处于监听状态,它会响应SYN+ACK报文,并且扫描者会发送ACK...

    TCP链接异常断开检测程序

    然而,在实际网络环境中,由于各种原因,如网络故障、主机崩溃等,可能导致TCP连接在一方看来仍然存在,而实际上已经中断。这种现象称为半开连接或者死连接。为了检测并处理这种情况,TCP引入了KEEPALIVE机制。 ...

    TCP网络编程登陆身份验证

    6. **异常处理**:在网络通信中,可能出现各种异常情况,如连接中断、超时等。程序需要捕获这些异常,并采取相应的处理措施,如重连、关闭连接等。 7. **资源释放**:认证成功后,客户端和服务器可以进行进一步的...

    labview TCP发送报文,TCP调试助手,断线自动连接

    这通常涉及到错误处理和定时重试机制,例如,当检测到连接断开时,程序可以设置一个定时器,一段时间后重新尝试连接。 5. **不间断通讯**:从压缩包的子文件名来看,"不间断通讯"可能指的是程序设计时特别考虑了...

    SuperSocketDemo:一个基于WPF + SuperSocket的TCP长连接小示例 实现心跳检测、断线重连、解决TCP粘包问题

    一个基于WPF + SuperSocket的TCP长连接小示例 SuperSocket 是一个轻量级, 跨平台而且可扩展的 .Net/Mono Socket 服务器程序框架。你无须了解如何使用 Socket, 如何维护 Socket 连接和 Socket 如何工作,我们可以有更...

Global site tag (gtag.js) - Google Analytics