TCP滑动窗口(Sliding Window)
什么是滑动窗口?
TCP滑动窗口是TCP协议中的一种流量控制机制,用于调节发送方和接收方之间的数据传输速率,以避免网络拥塞和提高传输效率。
滑动窗口机制允许发送方在不等待确认应答的情况下连续发送多个数据段,从而提高了网络的利用率。
TCP为什么使用滑动窗口?
我们都知道TCP是每发送一个数据包,都要进行一次ACK确认应答。当上一个数据包收到了ACK应答了再发送下一个。
为解决这个问题,TCP引入了窗口这个概念。即使在往返时间较长的情况下,它也不会降低网络通信的效率。
那么有了窗口,就可以指定窗口大小,窗口大小就是指无需等待确认应答,而可以继续发送数据的最大值。
窗口的实现实际上是操作系统开辟的一个缓存空间,发送方主机在等到确认应答返回之前,必须在缓冲区中保留已发送的数据。如果按期收到确认应答,此时数据就可以从缓存区清除。
假设窗口大小为3个TCP 段,那么发送方就可以「连续发送」3个TCP段,并且中途若有 ACK 丢失,可以通过「下一个ACK进行确认」。
图中的ACK 600确认应答报文丢失,也没关系,因为可以通过下一个确认应答进行确认,只要发送产收到了ACK 700确认应答,就意味着700之前的所有数据「接收方」都收到了。这个模式就叫累计确认。
发送方的滑动窗口
#1 是已发送并收到 ACK确认的数据:1~31 字节
#2 是已发送但未收到 ACK确认的数据:32~45 字节
#3 是未发送但总大小在接收方处理范围内(接收方还有空间):46~51字节#4 是未发送但总大小超过接收方处理范围(接收方没有空间):52字节以后
在下图,当收到之前发送的数据3236字节的ACK确认应答后,如果发送窗口的大小没有变化,则滑动窗口往右边移动5个字节,因为有5个字节的数据被应答确认,接下来5256字节又变成了可用窗口,那么后续也就可以发送52~56 这5个字节的数据了。
窗口大小如何确定?
TCP头里有一个字段叫Window,也就是窗口大小。
这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来
所以,通常窗口的大小是由接收方的窗口大小来决定的。
发送方发送的数据大小不能超过接收方的窗口大小,否则接收方就无法正常接收到数据。
窗口大小计算
TCP滑动窗口方案使用三个指针来跟踪在四个传输类别中的每一个类别中的字节。其中两个指针是绝对指针(指特定的序列号),一个是相对指针(需要做偏移)。
- SND.WND:表示发送窗口的大小(大小是由接收方指定的)
- SND.UNA(Send Unacknoleged):是一个绝对指针,它指向的是已发送但未收到确认的第一个字节的序列号,也就是 #2 的第一个字节。
- SND.NXT:也是一个绝对指针,它指向未发送但可发送范围的第一个字节的序列号,也就是 #3 的第一个字节。
- 指向 #4 的第一个字节是个相对指针,它需要 SND.UNA 指针加上SND.WND 大小的偏移量,就可以指向 #4 的第一个字节了。
那么可用窗口大小的计算就可以是:
可用窗口大小=SND.WND-(SND.NXT-SND.UNA)=20-(46-32)=6
接收方的滑动窗口
接收窗口相对简单一些,根据处理的情况划分成三个部分:
- #1 + #2)是已成功接收并确认的数据(等待应用进程读取)
- #3 是未收到数据但可以接收的数据
- #4 未收到数据并不可以接收的数据
其中三个接收部分,使用两个指针进行划分:
- RCV.WND:表示接收窗口的大小,它会通告给发送方。
- RCV.NXT:是一个指针,它指向期望从发送方发送来的下一个数据字节的序列号,也就是 #3的一个字节。
- 指向 #4 的第一个字节是个相对指针,它需要 RCV.NXT 指针加上 RCV.WND 大小的偏移量,就可指向 #4 的第一个字节了。
接收窗口和发送窗口的大小是相等的吗?
并不是完全相等,接收窗口的大小是约等于发送窗口的大小的。
因为滑动窗口并不是一成不变的。比如,当接收方的应用进程读取数据的速度非常快的话,这样的话接收窗口可以很快的就空缺出来。那么新的接收窗口大小,是通过TCP报文中的Window字段来告诉发送方。那么这个传输过程是存在时延的,所以接收窗口和发送窗口是约等于的关系,
出现“空洞“如何处理?
- 假设有一组数据通过TCP传输,TCP先将其分成若干段,假设有四个段seg1,seg2seg3,seg4,依次发送出去,此时假设接收端接收到了seg1、seg2、seg4;
- 此时接收端的行为是回复一个ACK包说明已经接收到,并将seg4进行缓存(保证顺序,产生一个seg3的hole空洞)
- 发送端收到ACK之后,就会将对应的数据包变为已确认状态,这个时候窗口向右移动;
- 假设接收端通告的WindowSize仍然不变,此时窗口右移,产生一些新的空位,这些是接收端允许发送的范畴:
- 对于丢失的seg3,如果超过一定时间,TCP就会重新传送**(重传机制)**,重传成功会seg3、seg4一块被确认,不成功,seg4也将被丢弃。
新的空位,这些是接收端允许发送的范畴: - 对于丢失的seg3,如果超过一定时间,TCP就会重新传送**(重传机制)**,重传成功会seg3、seg4一块被确认,不成功,seg4也将被丢弃。