TCP的拥塞控制是为了解决报文段在网络层节点之间的转发出现大量数据同时通过造成的排队长,丢包的问题,流量控制则是为了解决应用端在读取TCP接收到并缓存在应用端的数据缓存溢出的问题。
当一个报文段在网络层被分解成数据报在各个节点之间转发的时候,每个节点的策略是分组传输,意味着每次转发的时候都需要收到构成整个报文段的所有数据报,这样需要在节点路由器本地缓存已经到达的数据报,当有路由器的本地缓存不够的时候,就会出现数据报丢失的问题,这时就会引起TCP的重传,快速重传或者超时重传,如果缓存够用,但是也可能出现排队时间过长的问题造成TCP的超时重传,但是超时重传的数据报又是与排队数据报是重复的,所以多做了无用功,并增加了整体数据的排队时间。
为了解决上述的问题,增加整体的传输效率,TCP在流量控制的接受窗口之外另外有一个拥塞窗口,通过控制拥塞窗口的大小来控制发送报文的数量。而如何调节拥塞窗口的大小呢?TCP有两种强制的两种方式,分别是慢启动和拥塞避免,还有一种常用的是快速恢复。
慢启动是控制拥塞窗口的大小从1个最大报文段开始,当收到一个确认码之后将拥塞窗口的大小翻倍,直到出现超时重传,这是记录当前窗口的大小的一半的值为ssthresh(慢启动阀值),并且将拥塞窗口的大小设置为1个最大报文段,每收到一个确认码后将拥塞窗口的大小翻倍,直到拥塞窗口的大小为之前记录的ssthresh,这时进入拥塞避免模式。如果在慢启动期间出现收到三次同样的确认码引发的快速重传,这时记录拥塞窗口大小的一半ssthresh,并设置拥塞窗口的大小为ssthresh+3,进入快速恢复模式。
拥塞避免是每收到一个新的确认码会将拥塞窗口的大小+1,直到出现超时,就将拥塞窗口大小设置为1,ssthresh设置为当前窗口大小的一半,退回到慢启动模式,如果收到三个重复的确认码引发快速重传,则将ssthresh的设置为当前窗口大小的一半,窗口大小设置为ssthresh+3,进入到快速恢复模式。
快速恢复,每收到一个重复的确认码就将拥塞窗口的大小+1,直到收到新的确认码后就进入拥塞避免模式,如果在快速恢复模式中出现超时,则会将拥塞窗口的大小调为1,ssthresh设置为当前窗口大小的一半,重新进入慢启动模式。