TCPIP学习笔记:TCP拥塞控制
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
TCPIP学习笔记:TCP拥塞控制
简介
拥塞指的是
在某段时间,若对⽹络中某⼀资源的需求超过了该资源所能提供的可⽤部分,⽹络性能就要变坏。
这种情况就叫拥塞
(congestion)。
TCP模块任务:提供⽹络利⽤率,降低丢包率,保证⽹络资源对每条数据的公平性。
---- 拥塞控制
标准⽂档:,介绍了拥塞控制4个部分:慢启动(slow start)、拥塞避免(congestion avoidance)、快速重传(fast retransmit)和快恢复(fast recovery)。
拥塞控制for linux算法实现,有多种:reno算法、vegas算法、cubic算法等。
部分或全部实现。
查看⽅式(for Ubuntu 14):
$ cat /proc/sys/net/ipv4/tcp_congestion_control
cubic
我的PC是采⽤cubic算法。
术语介绍
拥塞控制最终受控变量:发送窗⼝(SWND,Send Window)。
也就是说,拥塞控制算法最终是通过控制SWND⼤⼩,来进⾏拥塞控制的。
发送窗⼝
在发送端发送缓存,存在4种类型数据,其中,发送窗⼝SWND是指(2)和(3)
(1)已经发送并且对端确认(Sent/ACKed)---------------发送窗外缓冲区外
(2)已经发送但未收到确认数据(Sent/UnACKed)----------发送窗内缓冲区内
(3)允许发送但尚未发送的数据(Unsent/Inside)---------发送窗内缓冲区内
(4)未发送暂不允许(Unsent/Outside)-----------------发送窗外缓冲区内
发送缓存4种类别数据的⽰意图
接收窗⼝
接收窗⼝指的是TCP报⽂头窗⼝字段,⽤于告诉发送端⾃⼰当前接收缓存⼤⼩。
发送者最⼤段⼤⼩ SMSS
MSS(Maximum Segment Size) TCP最⼤报⽂段长度(),指的是每⼀个TCP报⽂段中的数据字段的最⼤长度。
TCP报⽂段 = 数据字段 + TCP⾸部(20~40Byte)
MSS = MTU - sizeof(TCPHDR) + sizeof(IPHDR)
MTU:最⼤传输单元(含TCP头部、IP头部);TCPHDR:TCP报⽂头;IPHDR:IP报⽂头。
MSS与MTU含义见下图:
发送者最⼤段⼤⼩,称为SMSS(Sender Maximum Segment Size)。
如何通告MSS?
MSS的默认值是536byte,因此对端应能接受报⽂段长度是536 + 20(TCP固定⾸部) = 556byte的TCP报⽂。
如果想要改变MSS,就需要在TCP连接时,通过TCP报⽂头可变长的选项(option)字段(1byte类型+1byte长度+不定长内容),告知对端。
注意:MSS是设置好值后,再通告对⽅,⽽⾮与对⽅协商。
SWND⼤⼩的影响
如果SWND太⼩,会引起明显的⽹络延迟;反之,如果SWND太⼤,则容易导致⽹络拥塞。
既然接收窗⼝RWND可以控制发送窗⼝,为何还需要拥塞控制,⽽不直接⽤接收窗⼝进⾏控制?
虽然接收⽅可以通过接收通告窗⼝(RWND),来控制发送端SWND。
但是接收⽅并不知道⽹络拥塞情况,⽆法针对⽹络情况进⾏控制。
因此,发送端引⼊了⼀个称为拥塞窗⼝的(Congestion Windo, CWND)的状态变量。
实际的SWND值是RWND和CWND中较⼩者。
慢启动和拥塞避免
慢启动
TCP连接建⽴OK后,CWND初值IW(Initial Window),⼤⼩2~4SMSS -- 发送端最多能发送IW bytes数据。
此后,发送端每收到接收端的⼀个确认,其CWND就按下式增加:
CWND += min(N, SMSS), 其中,N是此次确认中包含的之前未被确认的字节数(1)
这样,CWND将按指数形式扩⼤,这就是慢启动。
慢启动算法理由:TCP模块刚开始发送数据时,并不知道⽹络的实际情况,需要⼀种试探的⽅式平滑地增加CWND的⼤⼩。
慢启动门限
如果不施加其他⼿段,慢启动必然使得CWND很快膨胀(慢启动并不慢),并最终导致⽹络拥塞。
⽽慢启动门限(slow start threadhold size, ssthresh),就是这样⼀个限制:
当cwnd < ssthresh时,使⽤慢开始算法;
当cwnd > ssthresh时,停⽌慢开始算法,改⽤拥塞避免算法;
当cwnd = ssthresh时,既可以⽤慢开始算法,也可以⽤拥塞避免算法;
ssthresh初始值16。
只要判断出现拥塞时,慢开始门限设为出现拥塞时发送窗⼝swnd的⼀半(但不能<2),然后把拥塞窗⼝cwnd重新设为1,执⾏慢开始算法。
⽬的:迅速减少主机发送到⽹络中的分组数,使得发⽣拥塞时路由器有⾜够时间把队列中积压的分组处理完毕。
拥塞避免算法
CWND按线性⽅式增加,从⽽减缓其扩⼤。
RFC 5681提到2种实现⽅式:
1)每个RTT时间内,按(1)式计算新的CWND,⽽不论该RTT时间内发送端收到多少个确认。
2)每收到⼀对新数据的确认报⽂段,就按式(2)来更新CWND。
CWND += SMSS * SMSS / CWND (2)
下图粗略地描述了慢启动和拥塞避免发⽣的时机和区别。
此外,我们假设当前ssthresh = 16SMSS⼤⼩(实际远不⽌这么⼤)
慢启动和拥塞避免,都是发送端在未检测到拥塞时,所采⽤的积极拥塞避免的⽅法。
下⾯介绍拥塞发⽣时(可能发⽣在慢启动阶段或拥塞避免阶段)拥塞控制的⾏为。
发送端如何判断拥塞发⽣?
传输超时,或者说TCP重传定时器溢出; ---- 拥塞避免
接收到连续3个重复的确认报⽂; ---- 快速重传,快速恢复
拥塞控制对这两种情况有不同的处理⽅式。
第⼀种情况,仍然使⽤慢启动和拥塞避免;第⼆种情况,则使⽤快速重传和快速回复(如果真的发⽣拥塞)。
如果发送端检测到拥塞发⽣是由于传输超时,即上述第⼀种情况,那么它将执⾏重传并做如下调整:
ssthresh = max(FlightSize / 2, 2 * SMSS) (3)
CWMD <= SMSS
其中,FlightSize是已经发送但未收到确认的字节数。
这样调整后,CWMD将⼩于SMSS,那么必然⼩于新的慢启动门限值ssthresh(根据式(3),ssthresh⼀定不⼩于SMSS的2倍),故⽽拥塞控制再次进⼊慢启动阶段。
何为TCP超时重传?
TCP服务必须能够重传超时时间内未收到确认TCP报⽂段。
为此,TCP模块为每个TCP报⽂段都维护⼀个重传定时器,该定时器在TCP报⽂段第⼀次被发送时启动。
如果超时时间内未收到对⽅的应答,TCP模块将重传TCP报⽂段并重置定时器。
所谓超时,是指定时器 > 最⼤往返时间RTT。
RTT是指⼀个数据报发送到⽬的地,然后到发送⽅收到确认所需的时间,这是测量RTT。
发送报⽂和确认报⽂并⾮数量上的⼀⼀对应,可能发送多次,确认⼀次,也可能是⼀⼀对应。
快速重传和快速恢复
如何通过接收到重复的确认报⽂段,判断⽹络是否真的发⽣拥塞?
发送端接收到重复的确认报⽂段可能情形:TCP报⽂段丢失,接收端收到乱序TCP报⽂段并重排等。
拥塞控制算法需要判断当收到重复的确认报⽂段时,⽹络是否真的发⽣了拥塞,或者说TCP报⽂段是否真的丢失了。
具体做法:
发送端如果连续收到3个重复的确认报⽂段,就认为拥塞发⽣了。
然后它启⽤快速重传和快速恢复算法来处理拥塞,过程如下:
1)当收到第3个重复的确认报⽂段时,按(3)式计算ssthresh,然后⽴即重传丢失的报⽂,⽽不是等到重传计时器超时,这称为快速重传。
并按式(4)设置CWND
CWND = ssthresh + 3 * SMSS (4)
2)每次收到1个重复的确认时,设置CWND = CWND + SMSS,⽽⾮从慢开始算法的cwnd=1开始。
此时,发送端可以发⽣新的TCP报⽂段(如果新的CWND允许的话)
3)当收到新数据的确认时,设置CWND = ssthresh(ssthresh是新的慢启动门限值,由第⼀步计算得到)
步骤1)称为快速重传,步骤2)3)称为快速恢复。
快速重传和快速恢复完成之后,拥塞控制将恢复到拥塞避免阶段。
这点由第3)步操作可得知。
总结
拥塞控制对象:发送窗⼝SWND. SWND <= min(RWND, CWND)
⽹络出现超时 => 采⽤慢开始算法 + 拥塞避免算法;
⽹络出现重传 => 快速恢复算法;
参考
[1]谢希仁. 计算机⽹络.第5版[M]. 电⼦⼯业出版社, 2008.
[2]游双. Linux⾼性能服务器编程[M]. 机械⼯业出版社, 2013.
[3]Postel J . Transmission control protocol; rfc793[J]. Rfc, 1981.()
[4]Тезисы, Статусдокумента, Авторскиеправа, et al. RFC 5681 TCP Congestion Control. 1996.()。