原创TCP超时重传机制探索
Posted brucemengbm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原创TCP超时重传机制探索相关的知识,希望对你有一定的参考价值。
TCP超时重传机制探索
作者:tll (360电商技术)
1)通信模型
TCP(Transmission Control Protocol)是一种可靠传输协议。在传输过程中当发送方(sender)向接收方(receiver)发送的数据丢失时,将引起发送方向接收方重传丢失的数据包。
其通信模型例如以下:
图1
2)超时重传
重传机制在实现数据可靠传输功能的同一时候,也引起了对应的性能问题:何时进行数据重传?怎样保证较高的传输效率?
重传时间过短:在网络因为拥塞引起丢包时。频繁的重传会进一步加剧网络拥塞。引起丢包。恶化网络传输性能。
重传时间过长:接收方长时间无法完毕数据接收。引起长时间占用连接线路造成资源损耗、传输效率较低等问题。
针对上述问题,TCP中设计了超时重传机制。
该机制规定当发送方A向B发送数据包P1时,开启一个时长为RTO(Retransmission Timeout)的重传定时器,假设A在RTO内未收到B对P1的确认报文,则觉得P1在网络中丢失,此时又一次发送P1。由此,引出RTO大小的设定问题。
对RTO大小的设定,因为的传输特性不同将导致发送与接收方完毕一次数据传输(发送与应答)的时间不同(例:通常有线网络的传输速率远高于无线网络)。因此固定大小的RTO无法满足不同环境下的传输需求。由此TCP採用针对详细传输环境动态測量的方式来确定当前时刻的RTO.
针对上述问题TCP中引入RTT(Round Trip Time),当中RTT为一个数据包从发出去到收到对该包确认的时间差,并依据RTT计算RTO.
因为RTT为单次測量的结果,经常受到网络拖延等因素的影响,波动较大,便记录多次的RTT值,通过加权移动的方式计算出一个更加合理的数值即SRTT(Smoothed RTT)。依据SRTT计算RTO.由此一次RTO的计算通过例如以下过程得出:
RTT---->SRTT---->RTO
对于上述数值的计算RFC793做了对应描写叙述,详细公式例如以下
SRTT = (α* SRTT ) + ((1-α) * RTT)
RTO = min[UBOUND, max[LBOUND, (β*SRTT)]]
当中 UBOUND 为timeout的上限 (e.g., 1 minute),
LBOUND 为timeout的下限 (e.g., 1 second),
α为平滑因子 (e.g., .8 to .9),
β为时延变化因子 (e.g., 1.3 to 2.0).
由上式能够看出RTO的计算相对保守。每次新到的RTT对RTO影响较少,如此将导致RTO在RTT变化较大的环境中不能做及时调整。更好的适应当前环境。如此。Van jacobson在Congestion Avoidance and Control 一文中对RTO的计算提出了一种高速算法
当中A为SRTT。M为最新RTT。D为偏差,g=1/2^n ,进一步
如此求得A与D,而RTO=A+4D,完毕对RTO计算。
Linux中详细实现參考tcp_rtt_estimator
当中而在Linux中RTO的最小值为200ms
#define TCP_RTO_MIN((unsigned)(HZ/5)) /* 200ms */
3)高速重传
TCP继续发展。重传机制得到进一步加强。出现了高速重传。例如以下图所看到的:
图2
高速重传机制规定:发生丢包时,在重传定时器被触发之前,当发送方连续收到3个对丢失数据包的重传请求时将引起马上重传。
如上图所看到的,数据包2在发送过程中丢失。然而在此时的重传定时器未到达之前,发送方连续收到4个ACK。当中第一个为对数据包1的确认。后3个ACK在对收到的数据包4,5。6做选择性应答的同一时候,连续3次告知对方缺少对数据包2的接收。由此触发高速重传,数据包10为对丢失数据包2的重传。
此时假设超时计时未到,将使得发送方能更加及时的发送出待重传数据包;假设超时计时到达。则相同马上发送待重传数据包。
由此可看出,高速重传机制在一定程度上弥补了超时重传机制。使得重传更加及时。
4)选择性重传
因为网络传输路径往往是复杂的。数据包在传输中可能发生丢包或者乱序到达,而TCP仅仅对连续的最后一个序列号做应答,使得乱序提前到达的数据包被重传,导致传输性能下降。
为改善此现状,RFC2018中提出了SACK(Selective Acknowledgement)。通过对ACK选项中加入已经接收的不连续数据块信息,通过对方不必反复发送对方已经接收的乱序数据块。
当中TCP首部中SACK选项例如以下所看到的:
图3
选项中分别用Left Edge of Block 与 Right Edge of Block来表示一个不连续数据块的第一个数据序号和最后一个数据序号+1。由此Right Edge of Block(n)与Left Edge of Block(n-1) – 1 的间隔表示丢失数据段。
图4
如上图所看到的。发送方在发送报文段5,6丢失的情况下,接收方应答报文9完毕对序列号201之前数据的应答,同一时候以SACK 301-401 501-601告知对方已接收数据段。发送方此时仅仅需重传丢失数据段201-300以及401-500之间的数据就可以。
选择重传的出现,在一定程度上大大减少了网络重传的数量。提高了网络吞吐量。
5)定时器的开启
图5
a. 重传计时器对哪些数据包进行计数?
TCP对每个连接採用一个重传计时器,当定时器已被使用时。当前发送的数据段不被计时。
如上图所看到的,因为发送数据段3时启动计时器,所以数据段4在计时器结束之前不再计时。
b. 重传计时器的起始时间?
如图发送数据段3,开启计时器,同一时候记录此时发送数据包的SEQ(257)。在接收到含有SEQ的ACK时,完毕计时。
如确认段5对SEQ 513之前数据的确认,包括RTT#2 计时起始的SEQ(257),此时RTT#2完毕计时。
同理RTT#3中开启计时时SEQ(769)此时确认段8中是对SEQ在769之前的确认(不包括769),所以此时RTT3并不结束。
6)重传次数与时间
图2描写叙述了网络中生成一次丢包与重传的情景,然而网络的传输场景是复杂的,引起网络的多次重传,针对连续的重传定时TCP採用了指数退让的方式来减少网络负载。
图6
如上图所看到的,在第12数据包发生丢失时,连续重传13,14,15。16,17号数据包。其间隔时间分别为6s,12s,24s。48s。96s
1)为什么不是准确的2倍?
Linux同BSD版TCP採用500ms作为一个滴答的定时器完毕定时功能。例定时6s则须要记录12次滴答就可以。
例如以下图所看到的,TCP设置一个6s定时器,则在第0个滴答到来时。完毕计时。因为计时開始发生在12到11的随意时间,所以此时完毕计时的时间将在5.5~6s之间。
图7
2)关于默认值
如此可看出,默认重传次数为3,最高重传次数为15
3)关于參数的设置与服务的配置
a. 内核中參数的设置
proc文件里查看当前网络协议栈等内核信息
sysctl –a 显示全部系统參数
例查看ipv4一些參数的设置:
图8
通过echo完毕对内核參数的动态改动。重新启动失效。
在/etc/sysctl.conf文件里完毕对參数的改动,使用sysctl –p 使之永久生效。
b. Web server中TCP的參数设置
Apache中对网络连接的设置:
图9
c. 应用程序对TCP连接參数的设置
通过setoptsock对socket选项完毕对连接參数的设置,包括拥塞算法、保活时间等參数
setoptsock---> tcp_setsockopt ---> do_tcp_setsockopt
当中do_tcp_setsockopt部分代码例如以下:
7)小结
TCP是一项复杂的协议,重传机制作为其保证进行可靠传输而存在,致使网络编程(TCP和UDP)是一个相对复杂的任务,能够使用默认參数进行传输,然而为了提升传输性能,往往须要针对详细的环境做对应的參数设置与细节处理。比如对MTU(Maximum Transmission Unit)的考虑,不同的网络传输环境MTU可能不同。採用同等较大的数据包传输层则会引起传输效率问题。数据传输包过大会引起分片,数据包过小带块利用率较低(当中TCP数据字节流传输。用户发送数据时在传输层受限与MSS大小完毕数据段切割。UDP为数据报传输,IP报文段大小受限于链路层MTU的大小。过大的数据包将完毕数据分片并带来性能损耗,所以应尽量在应用层完毕对报文段大小的确认,避免传输过程中不必要的分片过程)。
对保活连接时长和重传请求次数以及拥塞控制算法的选取都与应用场景有着密切的关系。假设须要进一步提升网络性能须要对详细參数做针对性调整。
<完>
-------------------------------------------------------------------------------------
黑夜路人,一个关注开源技术、乐于学习、喜欢分享的程序猿
博客:http://blog.csdn.net/heiyeshuwu
微博:http://weibo.com/heiyeluren
微信:heiyeluren2012
想获取很多其它IT开源技术相关信息。欢迎关注微信!
微信二维码扫描高速关注本号码:
?
以上是关于原创TCP超时重传机制探索的主要内容,如果未能解决你的问题,请参考以下文章