【计算机网络】TCP面试知识(3)滑动窗口

1、引入窗口概念的原因

我们都知道 TCP 是每发送⼀个数据,都要进⾏⼀次确认应答。当上⼀个数据包收到了应答了, 再发送下⼀个。

这个模式就有点像我和你⾯对⾯聊天,你⼀句我⼀句。但这种⽅式的缺点是效率⽐较低的。

如果你说完⼀句话,我在处理其他事情,没有及时回复你,那你不是要⼲等着我做完其他事情后,我回复你,你才能说下⼀句话,很显然这不现实。

【计算机网络】TCP面试知识(3)滑动窗口_第1张图片

所以,这样的传输方式有⼀个缺点:数据包的往返时间越⻓,通信的效率就越低。

为解决这个问题,TCP 引⼊了窗⼝这个概念。即使在往返时间较⻓的情况下,它也不会降低⽹络通信的效率。

那么有了窗⼝,就可以指定窗⼝⼤⼩,窗⼝⼤⼩就是指⽆需等待确认应答,⽽可以继续发送数据的最⼤值。

窗⼝的实现实际上是操作系统开辟的⼀个缓存空间,发送⽅主机在等到确认应答返回之前,必须在缓冲区中保留已发送的数据。如果按期收到确认应答,此时数据就可以从缓存区清除。

假设窗⼝⼤⼩为 3 个 TCP 段,那么发送⽅就可以「连续发送」 3 个 TCP 段,并且中途若有 ACK 丢失,可以通过「下⼀个确认应答进⾏确认」。如下图:

【计算机网络】TCP面试知识(3)滑动窗口_第2张图片

图中的 ACK 600 确认应答报⽂丢失,也没关系,因为可以通过下⼀个确认应答进⾏确认,只要发送⽅收到了 ACK700 确认应答,就意味着 700 之前的所有数据「接收⽅」都收到了。这个模式就叫累计确认或者累计应答。

2、窗口大小由哪⼀方决定?

TCP 头⾥有⼀个字段叫 Window ,也就是窗口大小。

这个字段是接收端告诉发送端⾃⼰还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能⼒来发送数据,⽽不会导致接收端处理不过来。

所以,通常窗口的大小是由接收⽅的窗口大小来决定的。

发送方发送的数据大小不能超过接收方的窗口大小,否则接收⽅就⽆法正常接收到数据。

3、发送方的滑动窗口(分成4部分)

【计算机网络】TCP面试知识(3)滑动窗口_第3张图片

  • #1 是已发送并收到 ACK确认的数据:1~31 字节
  • #2 是已发送但未收到 ACK确认的数据:32~45 字节
  • #3 是未发送但总⼤⼩在接收⽅处理范围内(接收⽅还有空间):46~51字节
  • #4 是未发送但总⼤⼩超过接收⽅处理范围(接收⽅没有空间):52字节以后

在下图,当发送⽅把数据「全部」都⼀下发送出去后,可⽤窗⼝的⼤⼩就为 0 了,表明可⽤窗⼝耗尽,在没收到ACK 确认之前是⽆法继续发送数据了。

【计算机网络】TCP面试知识(3)滑动窗口_第4张图片

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

【计算机网络】TCP面试知识(3)滑动窗口_第5张图片

程序是如何表示发送⽅的四个部分的呢?

TCP 滑动窗⼝⽅案使⽤三个指针来跟踪在四个传输类别中的每⼀个类别中的字节。其中两个指针是绝对指针(指特定的序列号),⼀个是相对指针(需要做偏移)。

【计算机网络】TCP面试知识(3)滑动窗口_第6张图片

  • SND.WND :表示发送窗⼝的⼤⼩(⼤⼩是由接收⽅指定的);
  • SND.UNA :是⼀个绝对指针,它指向的是已发送但未收到确认的第⼀个字节的序列号,也就是 #2 的第⼀个字节。
  • SND.NXT :也是⼀个绝对指针,它指向未发送但可发送范围的第⼀个字节的序列号,也就是 #3 的第⼀个字节。
  • 指向 #4 的第⼀个字节是个相对指针,它需要 SND.UNA 指针加上 SND.WND ⼤⼩的偏移量,就可以指向#4 的第⼀个字节了。

那么可⽤窗⼝⼤⼩的计算就可以是:可⽤窗⼝⼤ = SND.WND -(SND.NXT - SND.UNA)

4、接收⽅的滑动窗口(分为3部分)

接收窗⼝相对简单⼀些,根据处理的情况划分成三个部分:

  • #1 + #2 是已成功接收并确认的数据(等待应⽤进程读取);
  • #3 是未收到数据但可以接收的数据;
  • #4 未收到数据并不可以接收的数据;

【计算机网络】TCP面试知识(3)滑动窗口_第7张图片

其中三个接收部分,使⽤两个指针进⾏划分:

  • RCV.WND :表示接收窗⼝的⼤⼩,它会通告给发送⽅。
  • RCV.NXT :是⼀个指针,它指向期望从发送⽅发送来的下⼀个数据字节的序列号,也就是 #3 的第⼀个字节。
  • 指向 #4 的第⼀个字节是个相对指针,它需要 RCV.NXT 指针加上 RCV.WND ⼤⼩的偏移ᰁ,就可以指向#4 的第⼀个字节了。

接收窗口和发送窗口的⼤⼩是相等的吗?

并不是完全相等,接收窗⼝的⼤⼩是约等于发送窗⼝的⼤⼩的。

因为滑动窗⼝并不是⼀成不变的。⽐如,当接收⽅的应⽤进程读取数据的速度⾮常快的话,这样的话接收窗⼝可以很快的就空缺出来。那么新的接收窗⼝⼤⼩,是通过 TCP 报⽂中的 Windows 字段来告诉发送⽅。但是这个传输过程是存在时延的,所以接收窗⼝和发送窗⼝是约等于的关系。

学自小林coding所著的《图解网络》,侵删

你可能感兴趣的:(网络,java,linux,tcpip)