TCP窗口滑动
窗口滑动机制算是TCP最重要的一个机制。
窗口滑动机制,TCP维护一个窗口,来保证数据的可靠性,并且做流量控制,防止网络拥塞,合理的使用网络资源。
TCP发送端,通过接收方的通告,得到一个提供的窗口大小,这表明数据了可以发送的大小。当数据发出后,只有收到这个数据的确认号,窗口左侧才可以移动,否则会一直等待,直到超时重传。而右侧一般不会左移,会根据收到的报文的windows size和当前左侧确认的情况,决定能否右移。
例子:
以上图为例可以总结如下几点:
- 发送方不必发送一个全窗口大小的数据。
- 来自接收方的一个报文段确认数据并把窗口向右边滑动。这是因为窗口的大小是相对于确认序号的。
- 正如从报文段 7到报文段 8中变化的那样,窗口的大小可以减小,但是窗口的右边沿却不能够向左移动。
- 接收方在发送一个 ACK前不必等待窗口被填满。在前面我们看到许多实现每收到两个报文段就会发送一个 ACK。
上面的例子可以理解成C/S在一个LAN时的情况,但如果C/S中间隔了很多路由器,路由器间的速率情况不同。如果路由器之间有一个小速率的链路,那么如果当TCP握手完成后,就直接开始大数据量的发送,那么就极有可能造成拥塞,导致疯狂丢包,所以TCP有慢启动机制
慢启动,拥塞控制
拥塞避免算法和慢启动算法需要对每个连接维持两个变量:一个拥塞窗口cwnd和一个慢启动门限ssthresh。TCP输出例程的输出不能超过cwnd和接收方通告窗口的大小。
慢启动即为在RTT每经过一个单位时间,cwnd指数式增长(下述步骤的1,2)。
拥塞窗口 cwnd 初始化为1MSS,ssthresh=65535
- 刚开始,发送方会发送第一个报文S1,然后收到S1确认,cwnd增加一倍,cwnd = 2MSS
- 则现在可以发送两个数据段大小报文S2,S3,收到确认后S2 S3后cwnd再次翻倍,cwnd = 4MSS
- 无论在慢启动阶段还是在拥塞控制阶段,只要网络出现超时(拥塞),就将cwnd置为1,ssthresh置为cwnd的一半,然后又开始执行慢启动算法
- 当cwnd > ssthresh 时,执行拥塞控制,从该时刻起, cwnd以线性方式增加,在每个往返时间内最多增加 1个报文段。
整体流程如下图:
快重传
如果发送方设置定时器超时,那么很可能是网络出现了拥塞,致使TCP报文段在网络中的某处被丢弃。在这种情况下,TCP马上把拥塞窗口减少到1,并执行慢开始算法,同时慢开始门限值减半。上图是不采用快重传机制的情况。
快重传机制要求接收方每收到一个失序的TCP报文段后就立即发出重复确认(为了使发送方及早知道没有到达对方)而不要等待自己发送数据时才进行确认。
快重传算法规定:发送方只要连续收到3个重复确认就应当立即重传未被确认的报文段。
快恢复
由于我们不知道一个重复的ACK是由一个丢失的报文段引起的,还是由于仅仅出现了几个报文段的重新排序,因此我们等待少量重复的ACK到来。假如这只是一些报文段的重新排序,则在重新排序的报文段被处理并产生一个新的ACK之前,只可能产生 1 ~ 2个重复的ACK。如果一连串收到 3个或3个以上的重复ACK,就非常可能是一个报文段丢失了。于是我们就重传丢失的数据报文段,而无需等待超时定时器溢出。这就是快速重传算法。接下来执行的不是慢启动算法而是拥塞避免算法。这就是快速恢复算法。
快速恢复用在收到重复ACK,而超时会重新慢启动!
图片参考:https://blog.csdn.net/rock_joker/article/details/76769404