这个世界在一直变化着,任何事物如果停留在原地,最终是要被淘汰的,TCP的拥塞控制算法也是如此。
90年代中后期到21世纪以来,Internet得到迅猛发展,首先是拥塞现象变得越来越严重,其次是高带宽的网络出现,从100Mbps到1Gbps到10Gbps,再者很多对数据敏感的应用越来越多,如音视频应用等,这些对TCP的传统的拥塞控制算法提出了巨大的挑战。
首先来看高带宽和高时延网络情况,这种网络通常称之为长肥网络(Long Fat Network, LFN),也称之为高带宽时延乘积网络(High-Bandwidth-Delay-Product Network,BDP)。带宽时延乘积(BDP)通常表示网络通道的容量,也就是能够在网络中缓冲的数据量,显然带宽增大一倍或者时延增大一倍都会使得通道的容量加倍。当这个乘积变得越来越大时,TCP的局限性及开始暴露出来。一个100Mbps的网络,如果时延是100ms,那么BDP为100,000,000*0.1/8=1,250,000字节=1220.7K,如果是1Gbps的网络时延为100ms,那么BDP为12207K左右,如果TCP跑在这种网络上,那么效率是非常低的,从TCP的首部中我们可以看到TCP利用16位来表示接收窗口rwnd大小,16位能表示的最大值是65535,由于TCP的发送窗口是取拥塞窗口cwnd和对端的接收窗口rwnd两者之间的最小值,那么显然发送窗口最大只能到65535(以字节为单位),显然该值与我们上述的网络BDP相差得太远,那么TCP就只能发送一阵数据然后就等待ACK,极端下去就有点像“停等协议”了。这样TCP就无法充分利用网络带宽,浪费带宽现象严重。
窗口扩大选项:为了解决窗口过小的问题,TCP利用起了它的选项功能,从TCP的头部可以看到TCP预留了一定的选项功能,用于扩展等用途。窗口扩大选项增加了额外的16位来表示窗口大小,窗口的值由首部的16位大小和选项的16位值共同组成,不过不是用加法组成的,而是利用移位窗口值的幂来表示的,也就是说如果移位窗口值为10,那么窗口的最大值就是65535*210,这个值就比较大了,足够表示窗口的大小了。
好,窗口太小的问题解决了,我们再来看窗口增长的机制存在的问题。通过前面的TCP的拥塞控制的机制我们可以看到TCP的增长方式是AIMD原则的,即加法增大,在拥塞避免阶段,每次增加1,按照我们上面计算的网络环境1Gbps,100ms时延,其窗口大小到12,500,000,如果按照最理想的情况每个包大小为1500个字节的话,那么必须需要8333个包大小的拥塞窗口,也就是要8333个RTT才能增长到这个值,这个时间还随着RTT和带宽的增大而增大,而且在增长过程中只要一出现丢包的话,那么窗口就立即减半,此时又得重新开始增长,显然该增长函数不能满足现在网络的需要。
其次,传统的TCP总是把包的丢失解释为网络发生了拥塞,而假定链路错误造成的分组丢失是忽略不计的,这种情况是基于当时V. Jacobson的观察,认为链路错误的几率太低从而可以忽略,然而在高速网络中,这种假设是不成立的,当数据传输速率比较高时,链路错误是不能忽略的。在无线网络中,链路的误码率更高,因此,如果笼统地认为分组丢失就是拥塞所引起的,从而降低一半的速率,这是对网络资源的极大浪费。拥塞的判断需要两个连续的分组丢失。
最后就是网络的应用的多样化,音视频应用越来越多,而音视频基本上都是用UDP来传输数据,UDP不提供数据可靠性的保障,同时也没有拥塞控制和流控,因此当UDP和TCP在一起竞争的时候,如果造成丢包的话,此时TCP退避三舍,而UDP照样传输,显然会造成TCP的应用会变得奇慢,当然这个本质不是TCP的问题,但是给TCP带来了问题。
针对上述问题,TCP的拥塞控制进入了新的阶段,百花齐放,出现了很多研究热点,其中比较集中的方面有:“慢启动”过程的改进,基于速率的拥塞控制,ECN,和针对特殊网络(无线网络和卫星网络)的拥塞控制。最初提出了HSTCP,后来又出现了BI-TCP,CUBIC TCP、FastTCP、TCP-Westwood等一系列的改进,UDP的应用开始了TCP-Friendly的拥塞控制,出现了TFRC,最近又有了DCCP。