TCP滑动窗口机制
目的:提高通信速率
原因:TCP每发送一个数据,都要进行一次确认应答。当上一个数据包收到 应答后,再发送下一个数据包
举例:比如面对面聊天,我说一句话之后,我得等你回我一句后,我再说下一句,那如果我现在正好在做别的事情,没及时回复你,那你是不是要干等着,等我做完事情后,我回复你,你才能继续说下去,这样效率也低了,不现实

所以TCP这样的传输方式就有一个缺点:当数据包的往返时间越长,通信的效率就越低
所以为了解决这个问题,就引进了窗口这个概念。即使在往返时间较长的情况下,它也不会降低网络通信的效率。
窗口介绍:
窗口实际上上是操作系统开辟的一个缓存空间,发送方主机在等到确认应答返回之前,必须在缓冲区中保留已发送的数据。如果按期收到确认应答,此时数据就可以从缓存区清除。
窗口的大小是由哪一方决定?
TCP 头里有一个字段叫 Window,也就是窗口大小。
这个字段就是接收端告诉发送端自己这边还有多大的缓冲区可以用来接受数据,然后发送端就可以根据这个信息来发送数据,不会导致发太多导致接收端无法处理
所以,一般窗口的大小是由接收方的窗口大小来决定的。
发送方发送的数据大小不能大于接收方的窗口大小,否则接收方就无法正常接受数据。
下面分别介绍发送方窗口和接收方窗口
1、发送方窗口:
如下图例子:

-
#1 是已发送并收到 ACK确认的数据:1~31 字节
-
#2 是已发送但未收到 ACK确认的数据:32~45 字节
-
#3 是未发送但总大小在接收方处理范围内(接收方还有空间):46~51字节
-
#4 是未发送但总大小超过接收方处理范围(接收方没有空间):52字节以后
如下图,当发送方将一些数据发送出去,使得可用窗口的大小就为0了,在没收到接收方的ACK确认之前将无法继续发送数据

如下图,当收到之前发送的数据 32~36字节的 ACK 确认应答后,如果发送窗口的大小没有变化,则滑动窗口往右边移动 5 个字节,因为有 5 个字节的数据被应答确认,接下来52~56字节又变成了可用窗口,那么后续也就可以发送52~56这 5 个字节的数据了。

我们人是这样子理解表示的,那机器程序是怎么来表示发送方这4个部分?
TCP 滑动窗口方案使用三个指针来跟踪在四个传输类别中的每一个类别中的字节。其中两个指针是绝对指针(指特定的序列号),一个是相对指针(需要做偏移)。
如下图

先理解下这3个东西:
SND.WND、SND.UN、SND.NXT
-
SND.WND:表示发送窗口的大小(大小是由接收方指定的); -
SND.UNA:是一个绝对指针,它指向的是已发送但未收到确认的第一个字节的序列号,也就是 #2 的第一个字节。 -
SND.NXT:也是一个绝对指针,它指向未发送但可发送范围的第一个字节的序列号,也就是 #3 的第一个字节。 -
指向 #4 的第一个字节是个相对指针,它需要
SND.UNA指针加上SND.WND大小的偏移量,就可以指向 #4 的第一个字节了。
所以
可用窗口大 = SND.WND -(SND.NXT - SND.UNA)
2、接受方的窗口:
如下图例子:

接收方的窗口有以下这3种情况:
-
#1 + #2 是已成功接收并确认的数据(等待应用进程读取);
-
#3 是未收到数据但可以接收的数据;
-
#4 未收到数据并不可以接收的数据;
其中三个接收部分,使用两个指针进行划分:
-
RCV.WND:表示接收窗口的大小,它会通告给发送方。 -
RCV.NXT:是一个指针,它指向期望从发送方发送来的下一个数据字节的序列号,也就是 #3 的第一个字节。 -
指向 #4 的第一个字节是个相对指针,它需要
RCV.NXT指针加上RCV.WND大小的偏移量,就可以指向 #4 的第一个字节了。
那么现在有个问题:接收窗口和发送窗口的大小是相等的吗?
并不是完全相等,接收窗口的大小是约等于发送窗口的大小的。
因为滑动窗口并不是一成不变的。比如,当接收方的应用进程读取数据的速度非常快的话,这样的话接收窗口可以很快的就空缺出来。那么新的接收窗口大小,是通过 TCP 报文中的 Windows 字段来告诉发送方。那么这个传输过程是存在时延的,所以接收窗口和发送窗口是约等于的关系。

浙公网安备 33010602011771号