1. 什么是滑动窗口
TCP 每发送⼀个数据,都需要⼀次应答,然后继续发送,这样为每个数据包都进⾏确认应答,缺点是:数据往返时间越⻓,⽹络吞吐量越低。为了解决这个问题,TCP 引⼊了 窗⼝ 这个概念。即使在往返时间较⻓的情况下,它也不会降低⽹络通信的效率。⽽窗⼝的⼤⼩呢,就是⽆需等待确认应答,可以继续发送数据的最⼤值。
假设窗⼝⼤⼩为 3 个 TCP 段,那么发送⽅就可以「连续发送」 3 个 TCP 段,并且中途若有 ACK 丢失,可以通过「下⼀个确认应答进⾏确认」。如下图:
窗⼝的实现就是操作系统开辟的⼀个缓存空间,发送⽅主机在等到确认应答返回之前,必须在缓冲区中保留已发送的数据。如果按期收到确认应答,此时数据就可以从缓存区清除。
图中的 ACK 600 确认应答报⽂丢失,也没关系,因为可以通过下⼀个确认应答进⾏确认,只要发送⽅收到了 ACK700 确认应答,就意味着 700 之前的所有数据「接收⽅」都收到了。这个模式就叫 累计确认或者累计应答 。
2. 什么决定窗⼝⼤⼩
TCP 头部有⼀个字段叫 window ,窗⼝⼤⼩。
这个字段是接收端告诉发送端⾃⼰还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能⼒来 发送数据,⽽不会导致接收端处理不过来
通常窗⼝的⼤⼩是由接收⽅的窗⼝⼤⼩来决定的。
发送⽅发送的数据⼤⼩不能超过接收⽅的窗⼝⼤⼩,否则接收⽅就⽆法正常接收到数据。
3. 发送⽅的滑动窗⼝
下图就是发送⽅缓存的数据,根据处理的情况分成四个部分:
#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 个字节的数据了。
在收到 32-36 的 ACK 应答后,如果窗⼝⼤⼩不变,则滑动窗⼝先后移动 5 个字节,那么 52-56 变成可⽤窗⼝,可以继续发送数据。
4. 程序是如何表示发送⽅的四个部分的呢?
TCP 滑动窗⼝⽅案使⽤三个指针来跟踪在四个传输类别中的每⼀个类别中的字节。其中两个指针是绝对指针(指特定的序列号),⼀个是相对指针(需要做偏移)。
-
SND.WND
:表示发送窗口的大小(大小是由接收方指定的);
-
SND.UNA
(Send Unacknoleged):是一个绝对指针,它指向的是已发送但未收到确认的第一个字节的序列号,也就是 #2 的第一个字节。
-
SND.NXT
:也是一个绝对指针,它指向未发送但可发送范围的第一个字节的序列号,也就是 #3 的第一个字节。
-
指向 #4 的第一个字节是个相对指针,它需要 SND.UNA
指针加上 SND.WND
大小的偏移量,就可以指向 #4 的第一个字节了。
那么可用窗口大小的计算就可以是:
可用窗口大小 = SND.WND -(SND.NXT - SND.UNA)
已发送未确认 = (SND.NXT - SND.UNA)
5. 接收⽅滑动窗⼝
接收窗⼝根据处理的情况划分成三个部分:
- #1 + #2 是已成功接收并确认的数据(等待应用进程读取);
- #3 是未收到数据但可以接收的数据;
- #4 未收到数据并不可以接收的数据;
其中三个接收部分,使用两个指针进行划分:
RCV.WND
:表示接收窗口的大小,它会通告给发送方。RCV.NXT
:是一个指针,它指向期望从发送方发送来的下一个数据字节的序列号,也就是 #3 的第一个字节。- 指向 #4 的第一个字节是个相对指针,它需要
RCV.NXT
指针加上 RCV.WND
大小的偏移量,就可以指向 #4 的第一个字节了。
6. 接收窗⼝和发送窗⼝的⼤⼩是相等的吗?
并不是完全相等,接收窗口的大小是约等于发送窗口的大小的。
因为滑动窗口并不是一成不变的。比如,当接收方的应用进程读取数据的速度非常快的话,这样的话接收窗口可以很快的就空缺出来。那么新的接收窗口大小,是通过 TCP 报文中的 Windows 字段来告诉发送方。那么这个传输过程是存在时延的,所以接收窗口和发送窗口是约等于的关系。
7. 什么是TCP流量控制机制
TCP 流量控制(Flow Control)机制是为了防止发送方发送数据过快,导致接收方的缓冲区溢出而设计的一种控制机制。TCP 使用一种被称为“滑动窗口协议”的方法来实现流量控制。
主要概念
-
滑动窗口(Sliding Window):
- 滑动窗口是一种流量控制技术,它允许发送方在等待接收方确认之前发送多个数据包。
- 窗口大小决定了发送方在等待确认之前可以连续发送的最大数据量。
-
接收窗口(Receive Window):
- 接收窗口(rwnd)是接收方用于通知发送方自己可以接收的数据量。
- 接收窗口的大小通常由接收方的缓冲区大小决定,接收方会在每次发送确认包时,包含当前的接收窗口大小。
-
拥塞窗口(Congestion Window):
- 拥塞窗口(cwnd)是为了防止网络拥塞而引入的窗口。
- 拥塞控制是另一个独立的机制,用于调整发送方在网络中实际发送的数据量。
流量控制的工作原理
TCP 流量控制主要依靠接收窗口大小来进行。接收方通过在确认包中包含当前接收窗口大小,来告知发送方自己的接收能力。
1. 接收窗⼝ :接收⽅维护⼀个接收窗⼝,表示可以接收的数据段的范围。窗⼝⼤⼩可以根据接收⽅的处理能⼒进⾏调整。
2. 通告窗⼝⼤⼩ :接收⽅通过 TCP 报⽂中的确认信息,通告当前的接收窗⼝⼤⼩给发送⽅。发送⽅会根据这个窗⼝⼤⼩来控制发送数据的速率。
3. 窗⼝滑动 :随着接收⽅处理数据的能⼒,窗⼝可以向前滑动。接收⽅可以通告更⼤的窗⼝,表示它可以接收更多的数据。
4. 发送速率控制 :发送⽅会根据接收⽅通告的窗⼝⼤⼩来控制发送数据的速率。如果接收窗⼝变⼩,表示接收⽅的处理能⼒减弱,发送⽅会减慢发送速率,避免数据拥塞。
5. 动态调整 : TCP 流量控制是动态的,适应⽹络和接收⽅的变化。如果⽹络拥塞或接收⽅的处理速度变慢,流量控制可以适时地减少发送速率。