最初TCP采用的是每发一个数据,得收到ACK后再发送下一个。这种方式效率比较低下,如果期间出现网络延迟的话会影响下一个数据的发送。为了解决这种问题,TCP引入了窗口的概念。
窗口可以指定大小,而这个大小就是指无需等待确认应答,而可以继续发送数据的最大值
发送端和接收端会各自维护一个自己的窗口,分别是发送窗口(swnd)和接受窗口(rwnd)
窗口的大小由谁来决定?
TCP头里有一个window的字段,这个字段是接收端告诉发送端自己有多少缓冲区可以接受数据。发送端会根据这个值来发送数据。所以窗口的大小是根据接收方反馈的信息来决定的。
拥塞控制
当网络出现拥塞时,可能会有大量的数据延迟或者丢失,从而导致触发TCP的重传机制。但是正因为TCP不断地重发,反而会导致网络更加的拥堵。为了避免发送端的数据填满整个网络,TCP有一种机制叫做拥塞控制。
发送端有一个变量叫做拥塞窗口(cwnd),它会根据网络状态而动态的产生变化。和上面滑动窗口里说的发送窗口(swnd)和接受窗口(rwnd)关联起来的话,那么发送窗口=Min(拥塞窗口,接受窗口)。
拥塞窗口的变化规则:
网络中没有出现拥塞,cwnd就会增大
网络中有拥塞,cwnd就会减小
如何判断是否有拥塞?发送端是否在规定时间内接收到ACK报文
拥塞控制的四个机制
慢启动
刚开始建立好连接时,cwnd = 1,当接收到ACK后开始增长,指数型增加(1,2,4,8)
当cwnd到达ssthresh阈值后进入拥塞避免
拥塞避免
进入拥塞避免后cwnd的增长速度变成线性增长,每接收一个ACK增长1/cwnd
当触发了重传机制后进入拥塞发生
拥塞发生
既然重传机制分为超时重传和快速重传,那么也有对应的两种解决方法
当发生超时重传时,ssthresh会被重置为cwnd/2,然后cwnd被重置回1。也就是等于重新开始慢启动
当触发快速重传时,cwnd = cwnd/2,ssthresh = cwnd。这里cwnd只被减半,然后进入快速恢复
快速恢复(RFC2581,第五页)
快速恢复开启时,cwnd = ssthresh + 3,并因触发快速重传需要重发丢失的报文
如果还是收到重复ACK,那么cwnd = cwnd + 1
如果收到了新的ACK,那么cwnd = ssthresh,并回到拥塞避免