当前位置:首页 > 学习资源 > 讲师博文 > TCP/IP协议栈的心跳、丢包重传、连接超时机制实例详解

TCP/IP协议栈的心跳、丢包重传、连接超时机制实例详解 时间:2023-11-01      来源:华清远见

TCP/IP协议栈的心跳、丢包重传、连接超时机制实例详解

概述

大家都使用过在线会议软件,例如腾讯会议等。我们假设一个场景,当在开会时突然断网,这时最常见的现象是画面卡顿、音频停止,也就是我们常说的掉线了。通常这种断网一般TCPIP协议栈已经检测到网络异常,系统协议层已经将网络断开了;也可能软件应用层的心跳机制检测到网络故障,断开了与服务器的链接。对于系统TCPIP协议栈自身检测出来的网络异常,则可能存在两种情况,一是TCPIP协议栈自身的心跳机制检测出来的;二是TCP连接的丢包重传机制检测出异常。

如果用户希望在60内如果网络恢复,软件能够自动重连并继续保持在会议中,这时可以通过TCP/IP协议栈的TCP连接的心跳、丢包重传、连接超时等机制来完成。下面让我们一起来了解一下它们的使用方法吧。

TCP/IP协议栈的心跳机制

ACK机制

TCP建立连接时的三次握手:

TCP连接是可靠的,在发送数据前要建立连接,收到数据后都会给对方恢复一个ACK包,表明我收到你的数据包了。对于数据发送端,如果数据发出去后没有收到ACK包,则会触发丢包重传机制。不管是建立连接时,还是建立连接后的数据收发时,都有ACK包,TCP/IP协议栈的心跳包也是按照这个流程运行的。

心跳机制

TCP/IP协议栈有个默认的TCP心跳机制,这个心跳机制是和socket套接字(TCP套接字)绑定的,可以对指定的套接字开启协议栈的心跳检测机制。默认情况下,协议栈的心跳机制对socket套接字是关闭的,如要使用需人为开启。在Windows中,默认是每隔2个小时发一次心跳包,客户端程序将心跳包发给服务器后,接下来会有两种情况:

网络正常时:服务器收到心跳包,会立即回复ACK包,客户端收到ACK包后,再等2个小时发送下一个心跳包。其中,心跳包发送时间间隔时间keepalivetime,Windows系统中默认是2小时,可配置。如果在2个小时的时间间隔内,客户端和服务器有数据交互,客户端会收到服务器的ACK包,也算作心跳机制的心跳包,2个小时的时间间隔会重新计时。

网络异常时:服务器收不到客户端发过去的心跳包,没法回复ACK,Windows系统中默认的是1秒超时,1秒后会重发心跳包。如果还收不到心跳包的ACK,则1秒后重发心跳包,如果始终收不到心跳包,则在发出10个心跳包就达到了系统的上限,就认为网络出故障了,协议栈就会直接将连接断开了。其中,发出心跳包收不到ACK的超时时间称为 keepaliveinterval,Windows系统中默认是1秒,可配置;收不到心跳包对应的ACK包的重发次数probe,Windows系统是固定的,是固定的10次,不可配置的。

所以TCP/IP协议栈的心跳机制能检测出网络异常,不过在默认配置下可能需要很久才能检测出来,所以可以根据用户的需求来灵活配置keepalivetime和keepaliveinterval参数。

心跳参数设置

开启TCP/IP协议栈的默认心跳机制,不是对整个协议栈开启心跳监测,而是对指定的socket套接字开启。开启心跳机制后,还可以修改心跳的时间参数。先调用setsockopt给目标套接字开启心跳监测机制,再调用WSAIoctl去修改心跳检测的默认时间参数,相关代码如下所示:

上面的代码可以看到,先调用setsockopt函数,传入SO_KEEPALIVE参数,打开TCP连接的心跳开关,此时心跳参数使用系统默认的心跳参数值。紧接着,调用WSAIoCtrl函数,传入SIO_KEEPALIVE_VALS参数,同时将设置好时间值的心跳参数结构体传进去。下面对心跳参数结构体tcp_keepalive做个详细的说明:

keepalivetime:默认2小时发送一次心跳保活包,比如发送第1个保活包之后,间隔2个小时后再发起下一个保活包。如果这期间有数据交互,也算是有效的保活包,这个时间段就不再发送保活包,发送下个保活包的时间间隔会从收发的最后一条数据的时刻开始重新从0计时。

keepaliveinterval:发送保活包后,没有收到对端的ack的超时时间默认为1秒。假设和对端的网络出问题了,给对端发送第1个保活包,1秒内没有收到对端的ack,则发第2个保活包,1秒内没有收到对端的保活包,再发送下一个保活包,.....,直到发送第10个保活包后,1秒钟还没收到ack回应,则达到发送10次保活包的探测次数上限,则认为网络出问题了。

丢包重传机制

如果网络出故障时,客户端与服务器之间正在进行TCP数据交互,客户端给服务器发送数据包后因为网络故障收不到服务器的ACK包,就会触发客户端的TCP丢包重传,丢包重传机制也能判断出网络出现异常。对于TCP连接,客户端给服务器发送数据后没有收到服务器的ACK包,会触发丢包重传。每次重传的时间间隔会加倍,当重传次数达到系统上限(Windows默认的上限是5次,Linux默认的上限是15次)后,协议栈就认为网络出故障了,会直接将对应的连接关闭了。所以当网络出现故障时有数据交互,协议栈会在数十秒内检测到网路出现异常,就会直接将连接直接关闭掉。

决定报文是否有必要重传的主要机制是重传计时器(retransmission timer),它的主要功能是维护重传超时(RTO)值。当报文使用TCP传输时,重传计时器启动,收到ACK时计时器停止。

报文发送至接收到ACK的时间称为往返时间(RTT)。对若干次时间取平均值,该值用于确定最终RTO值。在最终RTO值确定之前,确定每一次报文传输是否有丢包发生使用重传计时器,下图说明了TCP重传过程:

对于丢包重传机制,可以通过给PC插拔网线来查看,先拔掉网线,等待几秒钟再将网线插上,可以发现接收端能够接收到丢包的数据。

connect连接超时控制

对于tcp套接字,我们需要调用套接字函数connect去建立TCP连接,阻塞式的socket,在Windows下,如果远端的IP和Port不可达,则会阻塞75s后返回SOCKET_ERROR,表明连接失败。所以当我们测试远端的IP和Port是否可以连接时,我们不使用阻塞式的socket,而是使用非阻塞式socket,然后调用select,通过select添加连接超时时间,实现连接超时的控制。具体实现可以参考如下代码:


连接超时的原因有很多,例如网络连接断开,电脑设置等原因。多次连接失败后可以提示用户检查电脑网络设置或网线是否正确接入。

 

上一篇:进程间的通讯方式之共享内存

下一篇:uboot启动过程中做了那些事-uboot和内核如何完成参数传递

戳我查看2020年嵌入式每月就业风云榜

点我了解华清远见高校学霸学习秘籍

猜你关心企业是如何评价华清学员的

干货分享
相关新闻
前台专线:010-82525158 企业培训洽谈专线:010-82525379 院校合作洽谈专线:010-82525379 Copyright © 2004-2024 北京华清远见科技发展有限公司 版权所有 ,京ICP备16055225号-5京公海网安备11010802025203号

回到顶部