【问题标题】:Does windows TCP stack sends ACK when the packet is received by the kernel or after the socket read?Windows TCP堆栈是否在内核接收到数据包时或在套接字读取后发送ACK?
【发布时间】:2014-02-21 22:16:04
【问题描述】:

我知道在大多数基于 UNIX 的系统中,内核一旦收到数据包就会发送 ACK。 但想知道 Windows 操作系统中的行为是否也相同。 (Windows 7)。

【问题讨论】:

  • 通常人们会期望 ack 来自 TCP 堆栈而不是客户端程序,除非可能一个粗心的客户端允许缓冲区填充到容量限制。但是您的前提不一定是正确的;无论应用程序代码在做什么,Nagle 算法都会导致对隔离数据包的确认延迟。
  • @ChrisStratton 我看不出“一个不专心的客户”与它有什么关系。套接字接收缓冲区中的数据由 TCP 确认,句号。
  • @ChrisStratton 接收缓冲区满时接收窗口变为零,所以发送方停止发送,所以不可能出现你描述的情况。这也是使应用程序的读取行为与 ACK 无关的原因。你似乎在这个简单的问题中引入了各种无关紧要的东西。
  • @user3250651 Unix 不会在内核收到数据包后立即发送 ACK。有许多限制条件,涉及延迟和合并的 ACK,这意味着它可以被推迟。但它与应用程序何时从套接字读取无关。

标签: windows tcp packet


【解决方案1】:

所有操作系统中的行为都是相同的。它由 RFC 793 定义。当 TCP 接收到数据时(或者,在延迟 ACK 的情况下,之后)执行 ACK。它与应用程序何时读取无关。

【讨论】:

  • 这是错误的,因为TCP_NODELAY 可以让你改变行为。
  • @DietrichEpp 没错,TCP_NODELAY 与它完全无关。 TCP_NODELAY 影响发送者,而不是接收者。 TCP 可能会选择延迟 ACK,仅此而已。这些都不意味着在应用程序读取时发送 ACK,这就是问题所在。
  • 除了 RFC 793 之外,它也无法以任何其他方式运行。如果是这样,客户端可以简单地通过向服务器发送请求而不从套接字读取回复来引发无休止的重新发送。如果 TCP 堆栈没有确认,则另一端的 TCP 堆栈必须假设数据包丢失。 TCP 保证交付,因此它必须重新发送。
  • 你错了;延迟/组合确认也是 TCP 效率措施的一个方面。
  • 问题是,一个 TCP 连接有 3 个可能的条件(嗯,还有几个,但这里有 3 个)。要么超时,只有在启用 keepalive 并且只有在 an eternity 之后才会发生这种情况(恶意客户端可以轻易地永远推迟)。或者,连接已关闭或以其他方式中断(在 FIN/ACK 或 ICMP 错误之后)。或者,最后,连接是活动的。如果连接是活动的,并且仍然存在 TCP 堆栈接受的未确认数据,则它别无选择,只能重新发送、重新发送和重新发送。因此 ACK 无法链接到客户端程序读取。
猜你喜欢
  • 2019-08-02
  • 1970-01-01
  • 2013-07-04
  • 1970-01-01
  • 2022-12-10
  • 1970-01-01
  • 1970-01-01
  • 2013-03-06
  • 2015-07-04
相关资源
最近更新 更多