首页 > 代码库 > TCP的流量控制和拥塞控制

TCP的流量控制和拥塞控制

1、TCP的流量控制

一般说来,我们总是希望数据传输的更快一些。但如果发送方吧数据发送的过快,接收方就可能来不及接收,就会造成数据的丢失。所谓的流量控制就是让发送方的发送速率不要太快,要让接收方来的及接收。

技术分享

设AB发送数据。在连接建立是,B告诉了A:“我的接收窗口wnd=400”。因此,发送方的发送窗口不能超过接收方的给出的接收窗口的数值。请注意,TCP的窗口单位是字节,不是报文段。我们应注意,接收方的主机B进行了三次流量控制。第一次把窗口减小到rwnd=300,第二次又减到rwnd=100,最后减到了rwnd=0,即不允许发送方再发送数据了。这种使发送方暂停发送的状态将持续到主机B重新发出一个新的窗口值为止。我们还应注意到,BA发送的三个报文段都设置了ACK=1,只有在ACK=1时确认好字段才有意义。

1.1、现在我们考虑一种情况,BA发送了零窗口的报文段后不久,B的接收缓存又有了一些存储空间。于是BA发送了rwnd=400的报文段。然而这个报文段在传送过程中丢失了。A一直等待收到B发送的非零窗口的通知,而B也一直等待A发送的数据,如果没有其他措施,这种互相等待的死锁局面将一直延续下去。

为了解决这个问题,TCP为每一个连接设有一个持续计时器,只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器。若持续计时器设置的时间到期,就发送一个零窗口探测报文段,仅携带一个字节的数据,而对方就在确认这个探测报文段时会给出现在的窗口值。如果窗口值仍为0,那么收到这个报文段的一方就重新设置持续计时器。如果窗口值不为0,那么死锁的僵局就可以打破了。

 

2、TCP的拥塞控制

网络拥塞往往是有许多的因素引起的。例如,当某个节点缓存的容量太小时,到达该节点的分组因存储空间而不得不被丢弃。现在设想将该节点缓存的容量扩展到非常大,于是凡是到达该节点的分组均可在节点的缓存队列中排队,不受任何限制。由于输出链路的容量和处理机的速度并没有得到提高,因此在这队列中的绝大多数的分组的排队等待时间将会大大增加,结果是上层软件只好把它们进行重传,由此可见,简单地扩大缓存的存储空间同样会造成网络资源的严重浪费,因而解决不了网络拥塞的问题。

犹如,处理机的速度太慢可能引起网络的拥塞,简单的将处理机的速度提高,可能会使得上述情况缓解一些,但往往又会将瓶颈转移到其他的地方。问题的实质往往是整个系统的各个部分的不匹配。只有所有的部分都平衡了,问题才会得到解决。

技术分享

2.1、拥塞控制与流量控制的关系

所谓拥塞控制就是防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前提,就是网络能够承受现有的网络负荷。它是一个全局性的过程,涉及到所有的主机、所有的路由器,以及降低网络传输性能有关的所有因素。

相反,流量控制往往指点对点通信量的控制,是个端到端的问题。流量控制所要做的就是抑制发送端发送数据的速率,以便接收端来得及接收。

拥塞控制和流量控制之所以常常被弄混,是因为某些拥塞控制算法是向发送端发送控制报文,并告诉发送端,网络已经出现麻烦,必须放慢发送速率。这点又和流量控制是很相似的。

 

3、几种拥塞控制方法

技术分享

 

1)慢开始

慢开始算法的思路是这样的。当主机发送数据时,如果立即把大量数据字节注入到网络,那么就有可能引起网络拥塞,因为现在并不清楚网络的负荷情况。经验证明,较好的方法是先探测一下,即由小到大主键增大发送窗口,也就是说,有小到大逐渐增大拥塞窗口数值,通常在刚刚开始发送报文段时,先把拥塞窗口增加到多一个MSS的数值,用这样的方法逐步增大发送饭的拥塞窗口cwnd,可以使分组注入到网络的速率更加合理。

2)拥塞避免算法的思路是让拥塞窗口cwnd缓慢的增大,及每经过一个往返时间RTT就把发送方的拥塞窗口cwnd1,而不是加倍。这样,拥塞窗口cwnd按线性规律缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢得多。

无论在慢开始还是在拥塞避免阶段,只要发送方判断网络出现拥塞,就是没有按时收到确认,就要把慢开始门限ssthresh设置为出现拥塞时的发送窗口值得一半,但是要不小于2,。然后把拥塞窗口cwnd重新设置为,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。

3)快重传

快重传算法首先要求接收方每收到一个失序的报文段后,就立即发出重复确认,为的是能够及早知道有报文段没有到达对方,而不要等待自己发送数据时才进行捎带确认,快重传算法规定,发送发只要一连收到3个重复的确认就应当立即重传对方尚未收到的报文段,而不必继续等待为丢失的报文段设置重传计时器到期。

4)快恢复

与快重传配合使用的还有快恢复算法,当发送方连续收到三个重复确认时,就执行乘法减小算法,把慢开始门限ssthresh减半。这是为了预防网络发生拥塞。请注意,接下去就不再执行慢开始算法了。由于发送方现在认为网络很可能没有发生拥塞,因此与慢开始不同之处是现在不执行慢开始算法,即把拥塞窗口cwnd的值设置为1,而是把cwnd值设置为慢开始门限ssthresh减半后的数值,然后开始执行拥塞避免算法,使拥塞窗口慢慢的线性的增大。

 

3.1、实际应用中的例子:

为什么http下载不是直接以可使用的最大速度下载而是一点一点地加快速度?如果直接以可使用的最大速度下载会有什么后果?

简单说,当用户向服务器建立连接时,没人知道两者之间有效带宽能有多大——可能是1G的光纤,也可能是坑爹的2G手机网络……
可采用的策略无非两种:
一是默认链路速率很大,一开始用能支持的最大流量发;发现对方接不过来再尝试更小的流量;
二是默认链路速率很小,用最低流量发;发完发现对方响应很快、没有丢包,就尝试加大速率发;没丢再加大;若出现拥塞,切换到拥塞控制算法继续尝试,直到找到链路允许的最大速率。
前者容易造成资源浪费,万一存在网络攻击还会急剧放大攻击的威胁能力;后者就好的多。
不要被慢开始(slow start)这个名字给误导了,它的意思是从低速开始试探流量,并不是“慢慢增加下载速率”。其实相关算法要求尽快探明链路速率上限、同时还能应对各种意外情况方为最佳。

 

TCP的流量控制和拥塞控制