tcp连接异常情况处理

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1.TCP连接中可能出现的异常断开情况

假设存在这样一种情况:在两个不同的主机Machine1、Machine2系统上分别运行两个应用程序Application1、Application2,在Application1与Application2的进程中存在一个TCP 链接TCPLink。它们的实际传输取决于物理链路的沟通PhysiLink。

图一:TCP通信情况模拟图

1.1程序/进程异常

如果TCPLink异常而Application1正常,TCPLink会被关掉并且告诉Application2,Application2也就关闭了该异常的TCPLink。这种情况会在TCPLink异常后的一次Socket 调用中通过返回值(C/C++)或者异常代码(C#)得知。因此在做程序开发的时候比较容易处理。

1.2物理链路异常

如果出现Machine1或者Machine2任何一个系统死机:假设Machine1系统异常,此时Machine2无法知道此TCP连接的失效,并一直认为连接正常。如果网络硬件故障(如网线拔掉、交换机断电):Machine1与Machine2都无法知道此TCP连接的失效,并一直认为连接正常。

以上这两种情况在编程时会变的非常糟糕,因为TCP连接将一直被认为有效,所有对此TCP Socket的调用都会正确返回,这显然是错误的。并且这种错误情况通常会持续很久。

2.异常断开情况影响分析

对于程序/进程异常,由于Socket调用中可以得到返回值。因此在做程序开发的时候比较容易处理。

对于物理链路异常,如果Machine1系统异常,如果Application2是FTP之类的服务器程序倒也无妨(一个连接存在时间比较长对它没有多大影响),如果是需要实时知道连接用户状态的即时通讯类服务器或者Application2是客户端则就会产生一系列的问题了。如果Machine1与Machine2都异常,Application1和Application2都会一直等下去,两端需要进行相似的处理。

3.异常断开情况的判断与处理

对于这种情况在MSDN里面是这样处理的,原文如下:

如果您需要确定连接的当前状态,请进行非阻止、零字节的Send 调用。如果该调用成功返回或引发WAEWOULDBLOCK 错误代码(10035),则该套接字仍然处于连接状态;否则,该套接字不再处于连接状态。

但是,在试验中发现,这种处理方法在很多时候根本无效,尤其对发生在物理链路层上的问题,很多情况下无法检测出网络已经异常断开了。

下面探讨一下能够使用的判断与处理方式以及优缺点。

1233.1定时发送简单约定帧

一般是服务器程序和客户端程序达成某种协议,客户端定时向服务器发送很小的数据包,即约定的简单帧,来告诉自己的状态,而服务器端程序则需要在每次收到用户的后更新用户超时的时间计数,当用户的时间计数超过指定时间,就可以认为这个用户已经系统异常终止,而终止之间的连接,并转告其他用户。客户端也可以通过接收服务器端返回的小数据包来判断服务器端的状态。

3.2Ping + Send/Receive

用Ping命令来判断网络本身状态,即确定物理链路层的状态。同时,用应用程序层的Send和Receive来进行程序/进程异常的判断。通过这两种方式的组合,一般能够正确得到网络的状态。当网络发生故障时,能够准确的定位其状态。

但是,当网络正常、应用程序正常时,对端的操作系统的设置可能会影响上述判断。即,当对端禁止向其发送Ping命令时,我们Ping的结果将始终为不通。考虑这种情况下,该方法存在一定的缺陷。

3.3KeepAlive-Timer

由于在应用层进行判断存在各种困难,那么是否可以考虑使用TCP底层的一些特性呢?通过思考,我想到可以利用TCP底层协议的KeepAlive-Timer进行网络状态的判断。但是需要改造。通过改造后,这将是一个比较可靠的判断方式。这将在下面作为重点单独介绍。

4.KeepAlive-Timer

44.1 TCP/IP协议结构以及底层定时器

网络协议通常分不同层次进行开发,每一层分别负责不同的通信功能。一个协议族,比如TCP/IP,是一组不同层次上的多个协议的组合。TCP/IP通常被认为是一个四层协议系统。

图二:TCP/IP协议族的四个层次以及不同层次的协议

上面的每一层分别负责不同的功能。链路层,通常包括操作系统中的设备驱动程序和计算机中对应的网络接口卡。它们一起处理传输媒介(如网线)的物理接口细节。网络层,处理分组在网络中的活动。运输层主,要为两台主机上的应用程序提供端到端的通信。在TCP/IP 协议族中,有两个互不相同的传输协议:TCP和UDP。TCP为两台主机提供高可靠性的数

据通信。它所做的工作包括把应用程序交给它的数据分成合适的小块交给下面的网络层,确认接收到的分组,设置发送最后确认分组的超时时钟等。由于运输层提供了高可靠性的端到端的通信,因此应用层可以忽略所有这些细节。应用层,负责处理特定的应用程序细节。

关键点:应用程序位于应用层,TCP协议在运输层,在数据流从运输层传递到链路层的过程中,TCP协议本身的底层实现正是我们要利用的所在。

TCP协议在实现的时候为每条连接建立了七个定时器。按照它们在一条连接生存期内出现的次序,分别为:connection establishment timer(连接建立定时器)、retransmission timer(重传定时器)、delayed ACK timer(延迟ACK定时器)、persist timer (持续定时器)、keepalive timer(保活定时器)、FIN_WAIT _ 2 timer、TIME_WAIT timer。

4.2KeepAlive-Timer (保活定时器)

在《TCP/IP协议详解卷2:实现》中,这样描述KeepAlive-Tmer:

KeepAlive-Tmer在应用进程选取了Socket的SO_KEEPALIVE选项时生效。如果连接的连续空闲时间超过2小时,保活定时器超时,向对端发送连接探测报文段,强迫对端响应。如果收到了期待的响应,TCP可确定对端主机工作正常,在该连接再次空闲超过2小时之前,TCP不会再进行保活测试。如果收到的是其他响应,TCP可确定对端主机已重启。如果连续若干次保活测试都未收到响应,TCP就假定对端主机已崩溃,尽管它无法区分是主机故障(例如,系统崩溃而尚未重启),还是连接故障(例如,中间的路由器发生故障或电话线断了)。

4.3KeepAlive-Timer工作机理分析

1 2 3 4 5 5.1 5.2 5.3 5.3.1 保活定时器在2小时

空闲后超时

收到一个报文段后,将复位连接的保活定时器,重设为2小时,并清零连接的空闲计数器。如果保活定时器超时(收到最后一个报文段2小时后),并且置位了Socket的保活选项,则TCP将向对端发送连接探测报文段。如果定时器超时,且未置位Socket的保活选项,则TCP将只复位定时器,重设为2小时,不向对端发送连接探测报文段。当然,如果应用进程调用了close,即使连接已空闲了2小时,TCP也不会发送连接探测报文段。

5.3.2 进行保活测试

当保活定时器发送连接探测报文后,如果对端无响应,TCP最多以75秒的间隔发送9

个连接探测报文段。TCP在确认连接已死亡之前必须发送多个连接探测报文段的一个原因是,对端的响应很可能是不带数据的纯ACK报文段,TCP无法保证此类报文段的可靠传输,因此,连接探测报文段的响应有可能丢失。如果连接总的空闲时间大于或等于2小时加10分钟,连接将被丢弃。从0秒起,每隔75秒连续9次发送连接探测报文段,直至600秒。675秒时(定时器2小时超时后的11.25分钟)连接被丢弃。

图三:保活定时器判断对端是否可达

相关文档
最新文档