· 以字节为单位的滑动窗口
什么是滑动窗口?
通信过程中一个传输方向上所有的字节的序号(seq)可以看做一个序列(这些序列在socket的缓冲区中),而窗口则是序列中的一个子集。该窗口用于做流量控制以及拥塞控制。
滑动窗口的单位是字节而不是分组。
一个连接的两端都各有一对窗口分别是发送窗口和接收窗口,因此一个连接有4个窗口,且是动态变化的。
发送窗口包含 已发送但未确认的数据 和 准备发送的数据。
接收窗口包含 按序到达但未被应⽤程序接收的数据、不按序到达 的数据。
窗口指针保存在套接字中。在不考虑拥塞的情况,发送端A的发送窗口和接收方B的接收窗口大小从整个传输过程来看是一致的(但不是强一致,并不总是一样大)。
发送窗口越大,发送方在收到确认前能连续发送的数据越多,在不考虑网络拥塞因素下传输效率越高。
· 滑动窗口工作过程
下面我们只观察发送方的发送缓冲区和接收方的接收缓冲区。
1、某一时刻,A 收到了 B 的确认报⽂段:报文携带的窗口值 20 字节,确认号为 31。A 可以把落⼊发送窗⼝中的序号字节⼀次连续性全部发送出去:边发送边接收确认。
2、下一刻A发送了31~41号字节,在确认前会保留在窗口中以便超时重传时使用。
B的接收窗口显示,B没有收到31,32~33是未按需到达的数据,要临时存放在接收窗口,不能上交给应用进程。B的接收窗口也不能移动。
3、下一刻B收到了31,B将31~33字节交付应用层,并从接收缓冲区中删除,且B接收窗口右移3个字节,发送ack=33的确认报文(假设确认报文的窗口大小字段仍是20)。A收到确认后窗口右移3字节。
当P2=P3时,可用窗口为0,会停止发送。
缓冲区与窗口的关联
先看发送方的发送缓存与发送窗口
发送窗⼝通常只是 发送缓存的⼀部分,具体来说 发送缓存 = 发送应用程序最后写入发送缓冲区的最后一个字节 - 发送窗口P1字节。缓冲区中,p1指针之前的数据由于已经发送和收到确认,因此被释放出缓冲区。
接收方的接收缓存与接收窗口
· 流量控制
流量控制是指动态控制滑动窗口的大小使得发送方发送数据的速率略小于或等于接收方接收的速率(接收速率其实又由应用程序取走接收缓冲区的速率决定),防止接收方的接收缓存溢出造成分组丢失。
流量控制的实现是通过在接收方的ACK报文携带窗口大小(假设大小X,X=接收方的接收缓冲区的空闲空间大小)同步给发送方,使发送方调整自己的可用窗口(P3-P2部分)为X。
需要注意的是发送窗口的p2-p1取决于ack号,P3-P2取决于ack报文中的窗口大小。
下面是一个流量控制的过程(不考虑拥塞的情况下):
图中rwnd(receiver window)表示容许的接收方窗口。
持续计时器
考虑一种情况,如果B向A发送了一个零窗口报文后,A停止向B发数据,后来B又向A发送了一个rwnd=400的ACK报文M。但M丢失了,A一直在等B的非零窗口通知,B也在等A发过来的数据,陷入死锁局面。
解决方法
TCP为每个连接设有一个持续计时器,只要一端A收到零窗口通知就启动该计时器,时间到期,A就发送一个仅携带1字节的“零窗口探测报文”。对端B就会确认这个报文的时候携带新的rwnd值。如果rwnd仍为0则重新启动持续计时器,否则A开始发送数据。
· 拥塞控制
什么情况下叫做拥塞?
网络中,链路容量(带宽)、交换机和路由器中的缓存和处理机都是网络的资源,在某段时间,若对网络中某一资源的需求超过了该资源能提供的部分,导致分组在链路中丢失,这种情况就叫拥塞。
拥塞的特点:
1、网络拥塞是由网络资源中的短板资源所决定的,只有所有类型的网络资源同时提高供给才会真正改善网络性能(例如你提高了带宽,但是路由器的缓存较小,瓶颈就转移到了缓存那里)。
2、拥塞趋于恶化,例如某个路由器没有足够的缓存,缓存溢出导致丢包和端系统重传,一旦重传又会加重网络拥塞。
3、拥塞的直接表现就是丢包和重传,当端系统的重传次数明显增加,就表明网络很可能发生了拥塞。举个例子:如果是带宽出现瓶颈,则RTT会增加,导致超时重传;如果是路由器缓存瓶颈,分组到达路由器后因缓存溢出而丢包,又会导致超时重传。因此重传就是拥塞的表现。
拥塞的其他指标(了解即可):
• 由于缺少缓存空间⽽被丢弃的分组的百分数;
• 平均队列⻓度;
• 超时重传的分组数;
• 平均分组时延;
• 分组时延的标准差,等等。
简单的记就是:丢包率、重传率和时延。
拥塞控制是防⽌过多的数据注⼊到⽹络中,使⽹络中的路由器或 链路不致过载。
拥塞控制和流量控制的区别
流量控制是解决端与端的发送与接收速率不匹配的问题,需要发送方同步接收方的接收速度;
拥塞控制是解决端系统的通信量与网络链路资源不匹配引起的路由器和链路过载问题,需要控制端系统注入到网络的数据量和速度。
TCP中的拥塞控制
首先需要知道,TCP的套接字中有2个关于窗口的变量,rwnd和cwnd分别表示接收方窗口和拥塞窗口,用来分别做流量控制和拥塞控制的。TCP头部的窗口大小其实指的是rwnd。
发送方的发送窗口 = Min(rwnd, cwnd)。
接下来我们假设接收方的接收缓存无限大,无需流量控制,发送方的发送窗口 = 拥塞窗口cwnd。
端系统如何主动感知网络拥塞?(端系统在什么情况下认为网络发送拥塞)
1、发送方重传计时器启动时(分组确认超时),就认为网络拥塞
2、发送方接收到3个冗余确认(即3个ack号相同的确认),因为这说明窗口发出的多个报文乱序到达,中间的某个报文丢失。
这2种情况都会导致发送方重传,但后者不一定是网络拥塞,而可能报文意外丢失,但也不排除是拥塞的可能。
拥塞控制的4种方法
慢开始、拥塞避免、快重传和快恢复。
这4种方法的基本思路是,只要网络没有拥塞,拥塞窗口就可以增大些,出现拥塞就减小些。
慢开始算法(慢启动)
慢开始的思路是从小到大以指数方式增加拥塞窗口的数值。慢开始发生在刚建立连接后的数据收发。
一开始发送方并不清楚网络的拥塞情况,就先将cwnd初始值设置为1~2个SMSS(发送方MSS),新的RFC标准则把初始cwnd设置为2~4,至于取2还是3还是4,取决于SMSS有多大。
在每收到⼀个对新的报⽂段的确认(重传的确认不算)后,发送方的拥塞窗⼝就增加⼀个 SMSS 的数值,因此cwnd会呈指数级别增长。
慢启动的窗口增长速度其实不慢(指数级别),之所以叫慢启动是因为它的初始cwnd值很小。
顺带一提 ,新建立的连接会用到慢启动,TCP 还实现了 慢启动重启 (SSR) 机制。这种机制会在持久连接空闲一定时间后重置拥塞窗口为初始cwnd值。道理很简单, 在连接空闲的同时,网络状况也可能发生了变化,为了避免拥塞,理应将拥塞窗 口重置回“安全的”默认值。
为了不让窗口无限的指数增长,提出了慢开始门限,当窗口大小超过了慢开始门限 ssthresh则使用拥塞避免算法线性增长窗口。
慢开始⻔限 ssthresh :
当 cwnd < ssthresh 时,使⽤慢开始算法;
当 cwnd >= ssthresh 时,停⽌使⽤慢开始算法⽽改⽤拥塞避 免算法;
拥塞避免算法
该算法是指:当cwnd超过慢开始门限后,每经过一个RTT,拥塞窗口就线性增长 cwnd = cwnd + 1。
快速重传算法
该算法是指:如果发送方连续收到3个重复ack号的确认,说明接收方收到了乱序的报文(某个中间报文丢失或者迟到),发送方会立即进行重传,而不是等到超时时间用完才重传,避免发送方误认为发生了网络拥塞。
中间报文的丢失或迟到极可能是意外丢失或迟到,而不是因为网络拥塞导致的丢失,但不排除拥塞的可能性。
快速重传可以是网络的吞吐量提高20%。
拥塞惩罚和快恢复算法
拥塞惩罚是指端系统检测到网络拥塞时(即发生重传时),降低自己cwnd窗口的行为。拥塞惩罚按超时重传和快速重传分为两种惩罚方式:
当发生超时重传时,发送方会认为网络出现拥塞,拥塞窗口cwnd会变成1。
当发生快速重传时,该分组很可能是意外丢失或迟到,但不排除拥塞的可能,因此cwnd会变为 cwnd/2。
快恢复算法是指当发生快速重传时,当前拥塞窗口大小减小一半,之后直接执行拥塞避免算法线性增长cwnd,而不是执行慢开始算法指数增长cwnd。
下面是TCP拥塞控制流程图:
整个拥塞惩罚机制逻辑如下:
超时重传的情况下:
• 慢开始⻔限 ssthresh = max(cwnd/2,2);
• cwnd = 1;
• 执⾏慢开始算法。
快速重传的情况下(快速恢复):
• 慢开始⻔限 ssthresh = 当前拥塞窗⼝ cwnd / 2 ;
• 新拥塞窗⼝ cwnd = 慢开始⻔限 ssthresh ;
• 开始执⾏拥塞避免算法,使拥塞窗⼝缓慢地线性增⼤。
无论是超时重传还是快速重传,都会导致慢开始门限减半,这会导致多次惩罚后,不再会执行指数增长,而是全变成线性增长。
TCP拥塞控制动态流程图
主动队列管理 AQM
对TCP拥塞控制影响最大的网络层策略是分组丢弃策略。该策略的内容为,到达路由器的分组会按先进先出原则放入到缓存队列中,一旦队列已满,后到达的分组会被丢弃。
这种丢弃策略会导致一连串分组的丢失和超时重传,这一方向的所有TCP连接都进入慢开始状态,这种情况叫做全局同步,全局同步会导致通信量突然下降,不一会儿通信量又突然增大(因为报文指数增长)。
为了避免全局同步,我们可以在队列长度到达某个警戒线时主动丢弃部分分组,而不是在分组数量达到最大队列长度时被动丢弃所有分组,这就是主动队列管理AQM。
AQM有不同的实现方式,比较主流的是随机早期检测RED。
RED规定路由器维持一个最小门限THmin和最大门限THmax。
队列⻓度L ⼩于最⼩⻔限 THmin,将新到达的分组放⼊队 列进⾏排队;
队列⻓度L 超过最⼤⻔限 THmax,将新到达的分组丢弃;
队列⻓度L 在最⼩⻔限 THmin 和最⼤⻔限 THmax 之间,按 照概率 p 丢弃新到达的分组。而且随着队列长度L的增加,p也会变大。