TCP - ACK 和接收窗口之间的相关性

网络工程 通讯协议 传输协议 联网 数据
2021-07-31 00:26:23

编辑:我想我现在明白了。所以一个简单的滑动窗口机制基本上假设正确接收的数据被立即处理。因此,确认意味着数据已被接收和处理,因此发送主机可以发送与被确认的字节一样多的新字节。

在现实世界的场景中,数据不会立即处理,而是由接收 TCP 缓冲,因此我们需要一个可变大小的接收窗口,因为确实有可能对字节进行确认但尚未处理(因此仍在接收缓冲区中) .

tcp 标头中的接收窗口属性基本上告诉我们发送 ACK 时缓冲区中剩余多少空间,因此发送方可以发送最多那么多字节(减去仍在传输中的未确认字节)以始终使一定不要溢出接收主机。

如果我正确理解这一点,我仍然会非常感谢答案。


原问题:

我目前正在阅读一本关于网络的书,并有一个关于流量控制的问题。

据我所知,每个主机都有一个发送缓冲区,其中保留正在传输(或已被其他主机接收)但尚未确认的字节序列。如果缓冲区内仍有空间未被尚未确认的字节序列占用,他基本上可以发送那么多字节而无需从其他主机接收任何内容。

另一方面,每个主机都有一个接收缓冲区,其中保留了正确接收但尚未被上层 read() 的字节序列。

发送方无需等待确认即可发送的字节数取决于接收缓冲区可以存储多少字节。这基本上是接收窗口标题字段中的内容。

现在我的问题:

在我读过的书(和其他资源)中,过程(滑动窗口)被解释为这样,每当发送主机收到某些字节的 ACK 时,他基本上可以“移动窗口”并有新的可用空间来发送更多数据。

我不明白的是 ACK 和接收窗口属性之间的相关性。我到处都读到,如果接收窗口为零(接收缓冲区基本上已满),则发送主机必须等待另一个 ACK​​。但是,ACK 不是只告诉我数据已成功接收,而不是“数据已从接收缓冲区读取(),因此有新空间,您可以发送更多字节”?

我看不到 ACK 和接收窗口属性之间的相关性。如果从 recv 缓冲区读取()字节而不是成功接收字节,则发送 ACK 是有意义的,但我怀疑是这种情况。

是否有可能主机发送的所有数据包都被确认但接收缓冲区仍然已满?这也有点奇怪,因为我认为一旦数据包被确认,它就会从发送缓冲区中删除。

在这种情况下,发送缓冲区中剩余的可用空间与主机仍可发送的数据之间没有相关性。因为如果所有数据包都被确认,则发送缓冲区可能是空的,但接收缓冲区可能已满(因为数据包已被接收但尚未 read()。

这可能有点混乱,因为我无法确定我的问题,尤其是因为我的英语水平不是很高,但我真的希望有人能够解决我的困惑。

1个回答

你很接近。

只要接收缓冲区中仍有空间,接收方就会确认一个段。当上层(=应用程序)不读取缓冲区或读取速度很慢时,空闲缓冲区空间用完并减少接收窗口以避免缓冲区溢出。

在每次接收时简单地确认将使发送方发送更多数据 - 除非上层实际读取数据,否则接收缓冲区会溢出。因此,如果接收应用程序实际上并未读取缓冲区,则接收堆栈会将接收窗口大小减小到当前空闲的接收缓冲区以避免溢出。

窗口大小可变并适应连接变量,使用复杂的算法。基本上,窗口的大小需要由带宽延迟乘积来决定——这个数据量需要“在飞行中”才能充分利用连接。由于有效带宽和往返时间在连接期间会发生变化,因此它们会被持续监控并反馈给算法。