首页 > 代码库 > TCP拥塞控制 2
TCP拥塞控制 2
解决传统TCP缺陷:
1、窗口太小,最大65535。
TCP利用了选项功能,其头部存在预留项,用于扩展等用途。窗口扩大选项增加了额外的16位来表示窗口大小,窗口的值由首部的16位大小和选项的16位值共同组成。
不过不是用加法组成的,而是利用移位窗口值的幂来表示的,也就是说如果移位窗口值为 10,那么窗口的最大值就是65535*210,这个值就比较大了,足够表示窗口的大小了。
2、数据包丢失,即认定为网络出现了拥塞
在高速网络中,这种假设是不成立的。如果笼统地认为分组丢失就是拥塞所引起的,从而降低一半的速率,这是对网络资源的极大浪费。拥塞的判断需要两个连续的分组丢失。
于是乎,就有了HSTCP和BI-TCP等一系列拥塞控制方法。
HSTCP
High-Speed TCP是由Floyd提出,基于AIMD准则的一种新的拥塞控制算法,能在高速度和大时延的网络中更有效地提高网络的吞吐率。它通过对标准TCP拥塞避免算法的增加和减少参数进行修改,从而实现了窗口的快速增长和慢速减少,但是它存在严重的RTT不公平性。
HSTCP提出的窗口增加和减小方法,先看拥塞控制中的两个公式:
cwnd = cwnd+a(cwnd)/cwnd ............................ (1)
cwnd = (1-b(cwnd)) * cwnd ............................ (2)
式 (1)是拥塞避免时的窗口增长方式,式(2)是发生了丢包后的窗口下降方式,其中a,b为两个函数,cwnd为其自变量,在标准TCP中a(cwnd)=1,b(cwnd)=0.5,也就是加法增大,乘法减小。
为了达到TCP的友好性,在窗口较低的情况下,也就是说非BDP的网络环境下,HSTCP采用的是和标准TCP相同的a和b,也就是一样的方式来保证两者之间的友好性。当BDP大时,也就是w较大时(HSTCP设定的临界值为38),采取新的a和b来达到高吞吐的要求:
根据不同的网络环境下使用不同的TCP窗口增长和降低参数,具体可以看RFC3649文档。
BIC-TCP
HSTCP,它通过简单的修改标准TCP的增长方式,从而达到了高吞吐。方法很简单,但是缺点在于,它存在严重的RTT不公平性. 公平性指共享同一网络瓶颈的多个流之间占有的网络资源相等。
BIC-TCP由North Carolina State University的网络研究实验室提出,该算法在提出不久后就成为了当时Linux内核中的TCP默认拥塞算法,使用非常广泛.(是linux采用cubic之前的默认算法)
BIC-TCP的本质:
BIC- TCP的提出者们发现了TCP拥塞窗口调整的一个本质:那就是找到最适合当前网络的一个发送窗口,为了找到这个窗口值,TCP采取的方式是(拥塞避免阶 段)每RTT加1,缓慢上升,丢包时下降一半,接着再来慢慢上升。BIC-TCP的提出者们看穿了事情的本质,其实这就是一个搜索的过程,而TCP的搜索方式类似于逐个遍历搜索方法,可以认为这个值是在1和一个比较大的数(large_window)之间,既然在这个区间内需要搜索一个最佳值,那么显然最好的方式就是二分搜索思想。
BIC- TCP就是基于这样一个二分思想的:当出现丢包的时候,说明最佳窗口值应该比这个值小,那么BIC就把此时的cwnd设置为max_win,把乘法减小后 的值设置为min_win,然后BIC就开始在这两者之间执行二分思想--每次跳到max_win和min_win的中点。
具体实现还有其他问题,比如防止传输的抖动,因而BIC-TCP选取了另外取了两个参考值Smax和Smin。BIC-TCP的具体实现可以参考内核代码/net/ipv4/tcp_bictcp.c
CUBIC
BIC-TCP的缺点:首先就是抢占性较强,它在探测阶段相当于是重新启动一个慢启动算法,而TCP在处于稳定后窗口就是一直是线性增长的,不会再次执行慢启动的过程。其次,BIC-TCP的窗口控制阶段增加了算法上的实现和性能分析复杂度。
CUBIC在设计上简化了BIC-TCP的窗口调整算法,CUBIC使用一个立方函数取代BIC-TCP的增长曲线。来看下具体细节:当某次拥塞事件发生时,Wmax设置为此时发生拥塞时的窗口值,然后把窗口进行乘法减小,乘法减小因子设为β, 当从快速恢复阶段退出然后进入到拥塞避免阶段,此时CUBIC的窗口增长开始按照“凹”式增长曲线进行增长,该过程一直持续直到窗口再次增长到Wmax, 紧接着,该函数转入“凸”式增长阶段。该方式的增长可以使得窗口一直维持在Wmax附近,从而可以达到网络带宽的高利用率和协议本身的稳定性。
鉴于CUBIC比BIC-TCP更出色的表现,在Linux2.6.18版本后,CUBIC取代了BIC-TCP,内核代码请参考/net/ipv4/tcp_Cubic.c。
TCP拥塞的优化算法还有N多多,比如
Fast TCP:从TCP vegas的思想发展而来,利用网络延时进行拥塞判断。
ECN:显式拥塞通知,该算法的思想是想借助路由器。路由器在发现有拥塞现象时在连接的TCP或者IP头里面打上拥塞的标记,让终端自己去根据标记进行处理。
UDT:UDT是一个开源的基于UDP实现的可靠传输协议,但是在UDT的拥塞算法与UDP或TCP没有关系,UDT采用的是一种带宽估计的算法。发送端的拥塞算法就是把拥塞窗口利用一个函数无限逼近于带宽值,这种思想对于传输的稳定性非常好,因为是一个无限逼近,所以永远不会超过带宽的值,而不是像TCP一样在平衡状态后继续一直往上增大窗口,从而在平衡状态能够维持比较久。
完成一个TCP的可用版本很容易,要实现一个高性能版本需要考虑的因素就多了去了。
不同环境:局域网、异构网、卫星网等等,每种网络的要求千差万别。
不同应用:有一直只发送小包(发送的包长度小于MSS)的应用,也有不停的发送大包的应用,还有两边同时发送和接收数据的应用。
传输效率,公平性,平稳性等等
参考;http://www.cnblogs.com/fll/archive/2011/11/15/2250437.html