【TCP协议】滑动窗口和流速控制

【TCP协议】滑动窗口和流速控制
文章目录三、流速控制四、面试题:滑动窗口和流速控制是怎么回事?
一、请求/响应模型
TCP 中每个发送的请求都需要响应 。如果一个请求没有收到响应,发送方就会认为这次发送出现了故障,会触发重发 。
大体的模型,和下图很像 。但是如果完全和下图一样,每一个请求收到响应之后,再发送下一个请求,吞吐量会很低 。因为这样的设计,会产生网络的空闲时间,说白了,就是浪费带宽 。带宽没有用满,意味着可以同时发送更多的请求,接收更多的响应 。
一种改进的方式,就是让发送方有请求就发送出去,而不是等待响应 。通过这样的处理方式,发送的数据连在了一起,响应的数据也连在了一起,吞吐量就提升了 。
二、滑动窗口( )
如上图所示:
下面我们重新设计一下不同类型封包的顺序,将已发送的数据放到最左边,发送中的数据放到中间,未发送的数据放到右边 。假设我们最多同时发送 5 个封包,也就是窗口大小 = 5 。窗口中的数据被同时发送出去,然后等待 ACK 。如果一个封包 ACK 到达,我们就将它标记为已接收(深绿色) 。
如下图所示,有两个封包的 ACK 到达,因此标记为绿色 。
这个时候滑动窗口可以向右滑动,如下图所示:
重传
如果发送过程中,部分数据没能收到 ACK 会怎样呢?这就可能发生重传 。
如果发生下图这样的情况,段 4 迟迟没有收到 ACK 。
这个时候滑动窗口只能右移一个位置,如下图所示:
在这个过程中,如果后来段 4 重传成功(接收到 ACK),那么窗口就会继续右移 。如果段 4 发送失败,还是没能收到 ACK,那么接收方也会抛弃段 5、段 6、段 7 。这样从段 4 开始之后的数据都需要重发 。
快速重传
在 TCP 协议中,如果接收方想丢弃某个段,可以选择不发 ACK 。发送端超时后,会重发这个 TCP 段 。而有时候,接收方希望催促发送方尽快补发某个 TCP 段,这个时候可以使用快速重传能力 。
例如段 1、段 2、段 4 到了,但是段 3 没有到 。接收方可以发送多次段 3 的 ACK 。如果发送方收到多个段 3 的 ACK,就会重发段 3 。这个机制称为快速重传 。这和超时重发不同,是一种催促的机制 。
为了不让发送方误以为段 3 已经收到了,在快速重传的情况下,接收方即便收到发来的段 4,依然会发段 3 的 ACK(不发段 4 的 ACK),直到发送方把段 3 重传 。
窗口大小的单位是?
窗口大小是 TCP 段的数量 。实际操作中,每个 TCP 段的大小不同,限制数量会让接收方的缓冲区不好操作,因此实际操作中窗口大小单位是字节数 。
三、流速控制
发送、接收窗口的大小可以用来控制 TCP 协议的流速 。窗口越大,同时可以发送、接收的数据就越多,支持的吞吐量也就越大 。当然,窗口越大,如果数据发生错误,损失也就越大,因为需要重传越多的数据 。
举个例子:我们用 RTT 表示 Round Trip Time,就是消息一去一回的时间 。
假设 RTT = 1ms,带宽是 1mb/s 。如果窗口大小为 1kb,那么 1ms 可以发送一个 1kb 的数据(含 TCP 头),1s 就可以发送 1mb 的数据,刚好可以将带宽用满 。如果 RTT 再慢一些,比如 RTT = 10ms,那么这样的设计就只能用完 1/10 的带宽 。当然你可以提高窗口大小提高吞吐量,但是实际的模型会比这个复杂,因为还存在重传、快速重传、丢包等因素 。
而实际操作中,也不可以真的把带宽用完,所以最终我们会使用折中的方案,在延迟、丢包率、吞吐量中进行选择,毕竟鱼和熊掌不可兼得 。