TCP采用端到端的拥塞控制,即网络层并未向传输层拥塞控制提供显式支持,端系统必须通过对网络行为(如:丢包,时延)的观察来判断,TCP报文段的丢失(超时或者收到3次冗余确认而得知)被认为是网络拥塞的一个迹象。
TCP连接的双方都维护着两个窗口,其中一个是作为发送方的窗口,也被称为拥塞窗口cwnd,它对发送方能向网络中发送流量的速率进行了限制,另一个自然是作为接收方的接收窗口。发送窗口的上限值=Min{拥塞窗口,接收窗口}。
发送方可以在RTT时间范围内连续发送cwnd个字节的数据,所以发送速率即为cwnd/RTT;发送方通过调整窗口大小来对发送数据的速率加以控制
TCP拥塞控制算法包含三个主要部分:慢启动、拥塞避免、快速恢复;慢启动和拥塞控制是TCP的强制部分;两者的差异在于对收到的ACK做出反应时增加cwnd长度的方式;快速恢复是推荐部分,对于TCP发送方并非是必须的
慢启动
TCP连接在开始的时候,其cwnd常设置为一个MSS,然后在慢启动状态每收到一个ACK,cwnd就增加一个MSS;这样的话,在慢启动阶段,发送速率是指数增加的(1,2,4,8…)
何时结束这种指数增长?有三种情况:发送了超时、发生了冗余ACK以及cwnd达到ssthresh。ssthresh是慢启动阈值的速记;在慢启动阶段,如果发生了超时事件,那么ssthresh就被设置为当前cwnd的一半,然后将cwnd置为1;当cwnd逐步增加到ssthresh时,再翻倍增加cwnd就有一点鲁莽了,所以此时TCP结束慢启动,进入拥塞避免模式。在拥塞避免模式里,TCP将更谨慎地增加cwnd;如果收到冗余ACK,那么TCP会做一次快速重传,然后进入快速恢复阶段;
拥塞避免
一旦进入拥塞避免状态,cwnd的值大约是上次遇到拥塞时的一半,所以TCP在每个RTT中,只将cwnd增加一个1个MSS大小;也就是说在拥塞避免阶段,cwnd是线性增加的;
当出现超时时,TCP将cwnd设置为1,然后将ssthresh更新为cwnd的一半;当收到冗余ACK时,TCP将cwnd减半,然后将ssthresh置为cwnd值的一半,并且进入快速恢复状态;
快速恢复
在快速恢复阶段,对于引起TCP进入该状态的缺失报文段,每收到一个ACK,cwnd增加一个MSS;最终,当对丢失报文段的一个ACK到达时,TCP降低cwnd后进入拥塞避免状态;如果出现超时事件,快速恢复在执行如同慢启动和拥塞避免中相同动作后,进入慢启动状态.