TCP堵塞控制

来源:互联网 发布:javascript书籍推荐 编辑:程序博客网 时间:2024/06/02 20:34

TCP堵塞控制

 

前言

在介绍之前,先来说一下最近可能让我感到迷惑的概念:

 

TCP校验和是一个端到端的校验和,由发送端计算,然后由接收端验证。其目的是为了发现TCP首部和数据在发送端到

 

接收端之间发生的任何改动。如果接收方检测到校验和有差错,则TCP段会被直接丢弃。

 

TCP校验和覆盖TCP首部和TCP数据,而IP首部中的校验和只覆盖IP的首部,不覆盖IP数据报中的任何数据。

 

TCP的校验和是必需的,而UDP的校验和是可选的。

 

TCPUDP计算校验和时,都要加上一个12字节的伪首部。

 

看完了吧,这些概念性的东西个人认为有必要记住,不难而且重要.

 

今天手贱的我想给我的硬盘加锁,加上锁之后发现电脑不识别了,呵呵,所以啊,我想写一篇文章就叫做手贱的危害.

 

 

 

引入

 

TCP协议中,我们使用连接记录TCP两端的状态,使用编号和分段实现了TCP传输的有序,使用滑窗(advertised window)来实现了发送方和接收方处理能力的匹配,并使用重复发送来实现TCP传输的可靠性.我们只需要将TCP片段包装成IP,扔到网络中就可以了.TCP协议的相关模块会帮我们处理各种可能出现的问题(比如排序,比如TCP片段丢失等等).最初的TCP协议就是由上述的几大块构成的.

 

看见我前面说的最初了吗,估计你肯定知道我要说最初的东西一般不容易满足人们日益增长的需求.到了80年代,网络开始变得繁忙.许多网络中出现了大量的堵塞(congestion).堵塞类似于现实中的堵车.网络被称为”信息高速公路”.许多汽车(IP)在网络中行驶,并经过一个一个的路口(路由器),直到到达目的地.一个路由器如果过度繁忙,会丢弃一些IP.UDP协议不保证传输的可靠性,所以丢弃就丢弃了.TCP协议需要保证传输的可靠性,当包含有TCP片段的IP包丢失时,TCP协议会重复发送TCP片段.于是,更多的”汽车”进入到公路中,原本繁忙的路由器变得更加繁忙,更多的IP包丢失.这样就构成了一个恶性循环.这样的情况被称为堵塞崩溃(congestion collapse).每个发送方为了保证自己的发送质量,而不顾及公共领域现状,是造成堵塞崩溃的主要原因.当时的网络中高达90%的传输资源可能被堵塞崩溃浪费.

 

为了解决这一问题,从八十年代开始,TCP协议中开始加入堵塞控制(congestion control)的功能,以避免堵塞崩溃的出现.多个算法被提出并实施,大大改善了网络的交通状况.直到今天,堵塞控制仍然是互联网研究的一个活跃领域.

 

 

 

公德

 

现实中,当我们遇到堵车,可能会希望兴建立交桥和高架,或者希望有交警来疏通.TCP协议的堵塞控制是通过约束自己实现的.TCP的发送方探测到网络交通拥堵时,会控制自己发送片段的速率,以缓解网络的交通状况,避免堵塞崩溃.简言之,TCP协议规定了发送方需要遵守公德!

 

我们先来说说堵塞是如何探测.TCP重新发送中,我们已经总结了两种推测TCP片段丢失的方法:ACK超时和重复ACK.一旦发送方认为TCP片段丢失,则认为网络中出现堵塞.

 

另一方面,TCP发送方是如何控制发送速率的呢?TCP协议通过控制滑窗(sliding window)大小来控制发送速率.TCP滑窗管理中,我们已经看见了一个窗口限制,就是advertised window size,以实现TCP流量控制.TCP还会维护一个congestion window size,已根据网络状态来调整滑窗大小.真实滑窗大小取这两个滑窗限制的最小值,从而同时满足两个限制(流量控制和堵塞控制)

 

我们将专注于congestion window

 

 

 

congestion window

 

congestion window总是处于两种状态中的一个.这两种状态是:慢启动(slow start)和堵塞避免(congestion avoidance)

 

 

上图是概念性的.实际的实施要比上图复杂,而且根据算法不同会有不同的版本.cwnd代表congestion window size.我们以片段的个数为单位,来表示cwnd的大小(同样是概念性的).

 

congestion windowslow start的状态开始.slow start的特点是初始速率低,但速率不断倍增.每次进入到slow start状态时,cwnd都需要重置为初始值1.发送方每接受到一个正确的ACK,就会将congestion window增加1,从而实现速率的倍增(由于累计ACK,速率增长可能会小于倍增).

 

congestion window的大小达到某个阀值ssthresh,congestion进入到congestion avoidance状态.发送速率会继续增长.发送方在每个窗口所有片段成功传输后,将窗口尺寸增加1(实际上就是每个RTT正价1).所以在congestion avoidance,cwnd线性增长,增长速率慢.

 

如果在congestion avoidance下有片段丢失,重新回到slow start状态,并将ssthresh更新为cwnd的一半.

 

我们看到,ssthreshslow startcongestion avoidance的切换点.而片段丢失是congestion avoidanceslow start的切换点.一开始sshthresh的值一般比较大,所以slow start可能在切换成congestion avoidance之前就丢失片段.这种情况下,slow start会重新开始,sshthresh更新为cwnd的一半.

 

总的来说,发送速率总是在增长.如果片段丢失,则重置速率为1,并快速增长.增长到一定程度,则进入到慢性增长.快速增长和慢速增长的切换点(ssthred)的值会随着网络状况(何时出现片段丢失)更新.通过上面的机制,让发送速率处于动态平衡,不断的尝试更大值.初始时增长快,而接近饱和时增长慢.但一旦尝试过度,则迅速重置,以免造成网络负担.

 

 

 

总结

 

阻塞控制有效的提高了互联网的利用率.阻塞控制的算法多种多样,并且依然不完善.一个常见的问题是cwnd在接近饱和时线性增长,因此对新增的网络宽带不敏感.

 

互联网利用”公德”来实现效率.”公德”和效率似乎可以并存.

 

目前为止,TCP协议的介绍就告一段落了,TCP的几大模块:分段与流,滑窗,连接,流量控制,重新发送,堵塞控制.这些东西你还能记得多少,我是忘得差不多了,忘了咋办?二次记忆!!

 

 

 

末尾备注

 

前面说过,如果在congestion avoidance下有片段丢失,重新回到slow start状态,并将sshthresh更新为cwnd的一半,但是有的人认为当发生超时重传,TCPsshthresh降低为cwnd值的一半,cwnd重新置为1,重新进入slow start.当发生快速重传时,TCPsshthresh降低为cwnd值的一半,cwnd重新设置为sshthresh的值,重新进入拥塞避免阶段.以上这两种情况都有,一个是TCP Reno,一个是TCP New Reno,也就是后来的改进协议增加了快速恢复阶段,目前互联网中使用的是New Reno.

 

置于流量控制和堵塞控制的关系个人认为相当于木桶原理.

1 0