最初在 Networking SE 中询问时,我被提到了这个站点。
我对 TCP 中的 rwnd 广告有一些疑问。我已经阅读了 RFC,但留下了没有答案的想法(或者我可能错过了一些东西)。也许有些答案取决于实现 - 在这种情况下,请使用您的经验回答,因为我想知道在一般情况下会发生什么。
TCP标准规定如下:
即使发送窗口为零,发送 TCP 也必须准备好从用户处接受并发送至少一个八位字节的新数据。
我认为这样做的原因是窗口探测消息包含一个八位字节的数据。然而,这让我想到:
我没有看到标准中规定探测数据包必须包含一个八位字节的新数据。是否有不同的方法来探测窗口大小?
如果这是唯一的方法,我想知道为什么重新发送旧段(带有旧序列号)是不够的。接收方是否必须在某个时刻仅确认窗口内的数据(意味着不一定要确认旧数据),这意味着我们必须将探测数据包视为该规则的例外?
一般来说,当窗口变大时,接收方会通知发送方吗?是否必须这样做(我知道确认可能会丢失,所以发件人可能不得不进行调查)?
探测数据包是否仅在
window = 0
或可能之前发送时发送?
为了清楚起见,窗口探测数据包没有特殊的数据包格式、标头或其他标识符。TCP 只是在需要探测窗口时发送一个标准的 TCP 数据包。它只是碰巧将该 TCP 数据包中的用户/应用程序数据限制为一个八位字节。
您刚刚引用了标准中的声明,即探测数据包必须包含至少一个八位字节的新数据,不是吗?如果您需要其他声明,您会在 RFC 793 和 RFC 1122 中找到声明,提醒您没有新应用程序数据的 Acks 无法可靠传输(这意味着您必须传输一些新数据才能知道它是否通过)。
可以想象 TCP 标准的作者可能会想出其他方式,但您引用的方式是他们在标准中提供的唯一方式。
这不是一个是否足够的问题,而是一个最好的方法的问题。如果您没有更多数据要发送,则无需探测窗口。如果您确实有更多数据要发送,为什么不使用它来探测窗口,而不是将带宽浪费在先前发送的(可能是确认的)数据上?
接收器应该只确认它收到的最新数据,即与从一开始接收到的所有数据是连续的(通过连续,我是说它是否有一个洞,因为它错过了一个或多个数据包,但得到了一个后来的数据包,它不能确认后面的数据包;它必须继续确认第一个洞之前的最后一个序列号)。
是的,一般来说,接收方会通过每个 Ack 通知发送方窗口大小的更新。
此外,在第 10 页的“窗口管理建议”下。在 RFC 793 的第 43 条中,作者建议 TCP 接收器“在窗口较大时发送另一个带有新窗口信息的确认”。该 RFC 早于定义 MAY/SHOULD/MUST 术语标准的 RFC 2119,但根据 RFC 2119 的要求级别指南,该建议似乎被视为 SHOULD。
我不知道有任何 RFC 更新 RFC 793 会使这种行为成为必须。
如果窗口不为零,那么单数据字节 TCP 段将不会真正被视为探测。例如,如果我有一个 telnet 连接向远程主机发送单独的击键,则每个击键都可能作为单数据字节 TCP 段发送。即使窗口大于 0 或 1,这些也可以在 telnet 等情况下发送,但它们不会被视为探测。