目录
滑动窗口
TCP除了保证可靠性之外,也希望能够尽可能高效的完成数据传输。滑动窗口就是一种提高效率的机制。以下是不引入滑动窗口的数据传输过程:
可以看到,主机A这边每次收到一个ACK才发送下一个数据。这个过程其实是比较低效的。
于是我们就引入了滑动窗口:
这样,就不是一次发送一条数据了,而是一次发送一组,再批量等待一组ACK。就把一条一条发送转化成批量发送了。就把等待时间重叠了,提高了效率。
不等待ack,批量发送多少数据,这个过程就是称为“窗口大小”。
分析:上述过程,收到了2001的ack,此时这个1001-2000的数据就得到了确认,标记成灰色了。接下来,当然要继续等待2001-5000的ack,与此同时,也发送一个新的数据,5001-6000。(此时要等待ack的数据还是四组数据)就像一个固定大小向后滑动的窗口一样。
注意:滑动窗口中,批量发送4组数据之后,不是等到4个都回来才继续发送新的数据,而是收到一个ack,就往后发一个新的。
问题:在滑动窗口中,收到的ack不一定是按照发送顺序返回的,有可能1001-2000和2001-3000的数据先发,但是3001-4000的数据的ack先返回了,这样该怎么办?
3001的意思是3001之前的数据已经收到了,这样滑动窗口就可以向后走两格。
那如果3001之前的数据丢包了,怎么办?
有两种情况:(滑动窗口之下,搭配的丢包处理机制,是很高效的,称为快速重传)
虽然主机A仍然在继续给B往后发送,接下来的每个数据,B都是再向A索要1001这个数据报。
A这边连续收到若干个1001这样的ack,就明白了,原来是1001-2000这个数据丢了,于是紧接着A就将1001-2000这个数据重传。B收到之后,会从7001开始发送ack。1001-2000的数据就像一块拼图,一但拼图凑齐,B就会从最新的7001开始发送。
因为对于B来说有一个接收缓冲区,数据报都是先存在接收缓冲区里的。当缓冲区存在某个缺口的时候,返回的ack,确认序号都是在索要缺口的数据。
超时重传和快速重传是否是冲突的? 当然不冲突。两者只是不同情况下采取的重传策略。快速重传相当于在滑动窗口下的特殊变种。
注:如果TCP传输的数据比较少,不频繁,此时就不会触发滑动窗口,仍然按照超时重传的方式来解决丢包问题。如果短时间传输大量数据,此时才能触发滑动窗口。此时才触发快速重传,按照ack反馈的次数来解决丢包问题。
重要结论:滑动窗口,说是提升效率的机制,更准确地说,是“亡羊补牢”的机制。TCP为了保证可靠性,牺牲了很多效率。引入滑动窗口,是让效率上的牺牲,变少一些,但是仍然是存在牺牲的。再如何滑动窗口,速度也不可能比UDP这种没有可靠机制的协议更快。
流量控制
滑动窗口的窗口大小是可变的。可以通过窗口大小,来控制发送方的发送速度。窗口越大,单位时间发的数据就越多,效率就越高。窗口越小,单位时间发的数据就越少。
通常情况下,肯定是希望尽可能高效的传输。但是高效的前提一定是可靠性。
如果发送速度太快,接收方处理不过来,此时还可能引起丢包。
接收方根据自身的处理能力,反向制约发送方的速度,是双方达成一个“平衡”。这样的机制,就称为“流量控制”。
如何衡量接收方的处理速度? 接收方有一个接收缓冲区(阻塞队列)。
以空闲空间大小,作为发送方发送数据的窗口大小。接收方给发送方返回ack,把这个数值告诉发送方,在ack报文中,在tcp报头里,指定一个字段,表示上述的空闲空间大小。
窗口拓展因子,就可以使窗口大小大于64kb。
发送方就可以按照上述窗口大小,决定下一轮数据发送的窗口大小了。
拥塞控制
拥塞控制和流量控制类似,都是和滑动窗口搭配的机制。流量控制是站在接收方的角度,影响发送方的速度。而拥塞控制是站在发送方的角度,影响接收方的速度。
流量控制的时候,很容易定量的来衡量,接收缓冲区的剩余空间大小,用这个作为发送窗口大小。但是考虑中间结点,就复杂了。每次走的路径,每个设备的处理能力,繁忙程度,都不一样。
但是无论中间结构多复杂,tcp都会把它们视为一个整体,然后通过“实验”的方式,找到一个合适的窗口大小(发送速度)。具体流程如下:
刚开始按照小的速度,小的窗口来发送数据。如果没有出现丢包(说明中间链路非常通畅),就可以增加速度,增加窗口大小。如果还是没丢包,仍然很通畅,就继续增加速度,继续增加窗口大小。.........增加到一定程度,发送速度非常快了,此时可能某个设备到达瓶颈,出现丢包了。此时,发送方立即减少窗口大小,继续发送,看是否还丢包。如果不丢包,再继续尝试加。如果丢包,就继续尝试减。这样就能找到一个合适的窗口大小的值,就可以不丢包,并且还能以比较快的速度完成传输。
由于网络是复杂的,也是多变的。按照上述方式,动态调整,随时适应网络中的变化。
拥塞控制的窗口,影响发送速度。流量控制窗口,也会影响发送速度。这俩窗口哪个小,就听那个的。
拥塞控制窗口大小动态变化是否有规律?
1)刚开始,以比较小的窗口,来传输数据。主要因为刚开始不知道网络是否拥堵,先试试看。
2)按照指数方式扩大窗口(*2)
这里慢启动说的“慢”说的是刚开始窗口大小比较小,传输速度慢。而不是窗口大小的变化速度慢(指数增长非常快的)。
3)指数增长的过程中,达到某个阈值,就要变成线性增长(+n)。
4)线性增长,也是增长,发送速度越来越快。增长到一定程度,就会出现丢包。此时,发送方大概就摸到了网络的大概能力是在啥样的水平。此时就会立即把窗口变小(发送速度减下去)。
5)缩小有两种方式
1、直接缩到底(回到了最初慢启动的时候),接下来指数增长,线性增长。
2、缩到出现丢包时,窗口大小一半这样的位置,接下来线性增长。
第一种方式比较低效,现在已经废弃了。第二种方式是当前实际使用的方式。
以上关于滑动窗口,希望对你有所帮助。