TCP 滑动窗口
所以,这样的传输⽅式有⼀个缺点:数据包的往返时间越⻓,通信的效率就越低。 为解决这个问题,TCP 引⼊了窗⼝这个概念。即使在往返时间较⻓的情况下,它也不会降低⽹络通信的效率。 那么有了窗⼝,就可以指定窗⼝⼤⼩,窗⼝⼤⼩就是指⽆需等待确认应答,⽽可以继续发送数据的最⼤值。 窗⼝的实现实际上是操作系统开辟的⼀个缓存空间,发送⽅主机在等到确认应答返回之前,必须在缓冲区中保留已 发送的数据。如果按期收到确认应答,此时数据就可以从缓存区清除。 假设窗⼝⼤⼩为 3 个 TCP 段,那么发送⽅就可以「连续发送」 3 个 TCP 段,并且中途若有 ACK 丢失,可以 通过「下⼀个确认应答进⾏确认」。
ACK 600 确认应答报⽂丢失,也没关系,因为可以通过下⼀个确认应答进⾏确认,只要(窗口内)发送⽅收到了 ACK 700 确认应答,就意味着 700 之前的所有数据「接收⽅」都收到了。这个模式就叫累计确认或者累计应答。
窗⼝⼤⼩由哪⼀⽅决定?
TCP 头⾥有⼀个字段叫 Window ,也就是窗⼝⼤⼩。 这个字段是接收端告诉发送端⾃⼰还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能⼒来 发送数据,⽽不会导致接收端处理不过来。 所以,通常窗⼝的⼤⼩是由接收⽅的窗⼝⼤⼩来决定的。 发送⽅发送的数据⼤⼩不能超过接收⽅的窗⼝⼤⼩,否则接收⽅就⽆法正常接收到数据。
发送⽅的滑动窗⼝
1 是已发送并收到 ACK 确认的数据:1~31 字节
2 是已发送但未收到 ACK 确认的数据:32~45 字节
3 是未发送但总⼤⼩在接收⽅处理范围内(接收⽅还有空间):46~51 字节
4 是未发送但总⼤⼩超过接收⽅处理范围(接收⽅没有空间):52 字节以后
在下图,当收到之前发送的数据 3236 字节的 ACK 确认应答后,如果发送窗⼝的⼤⼩没有变化,则滑动窗⼝往
右边移动 5 个字节,因为有 5 个字节的数据被应答确认,接下来 5256 字节⼜变成了可⽤窗⼝,那么后续也就
可以发送 52~56 这 5 个字节的数据了
接收⽅的窗⼝,接收窗⼝相对简单⼀些,根据处理的情况划分成三个部分:
1 + #2 是已成功接收并确认的数据(等待应⽤进程读取); 1,2 合为一个
3 是未收到数据但可以接收的数据
4 未收到数据并不可以接收的数据
接收窗⼝和发送窗⼝的⼤⼩是相等的吗?
并不是完全相等,接收窗⼝的⼤⼩是约等于发送窗⼝的⼤⼩的。 因为滑动窗⼝并不是⼀成不变的。⽐如,当接收⽅的应⽤进程读取数据的速度⾮常快的话,这样的话接收窗⼝可以 很快的就空缺出来。那么新的接收窗⼝⼤⼩,是通过 TCP 报⽂中的 Windows 字段来告诉发送⽅。那么这个传输过 程是存在时延的,所以接收窗⼝和发送窗⼝是约等于的关系。
发送⽅不能⽆脑的发数据给接收⽅,要考虑接收⽅处理能⼒。 如果⼀直⽆脑的发数据给对⽅,但对⽅处理不过来,那么就会导致触发᯿发机制,从⽽导致⽹络流 ᰁ 的⽆端的浪 费。 为了解决这种现象发⽣,TCP 提供⼀种机制可以让「发送⽅」根据「接收⽅」的实际接收能⼒控制发送的数据量, 这就是所谓的流量控制。
两方的窗口会互相同步 最后窗⼝都收缩为 0 了,也就是发⽣了窗⼝关闭。当发送⽅可⽤窗⼝变为 0 时,发送⽅实际上会定时发送窗⼝ 探测报⽂,以便知道接收⽅的窗⼝是否发⽣了改变,