【问题标题】:Doubt regarding Winsock Kernel Buffer and Nagle algorithm关于 Winsock Kernel Buffer 和 Nagle 算法的疑问
【发布时间】:2009-06-19 11:41:28
【问题描述】:

在阅读this 文章时,我有一个疑问。

我了解到,在传输小数据时,默认启用 Nagle 算法以合并小数据包。这导致在传输之前缓存一些数据。我相信 Winsock Kernel Buffer 是缓存发生的地方。如果我错了,请纠正我。

这是否意味着如果使用 SO_SNDBUF 选项将 Winsock 内核缓冲区设置为零,是否会禁用 Nagle 算法?

如果没有,那么WINSOCK在哪里缓存小数据?

【问题讨论】:

    标签: windows winapi winsock


    【解决方案1】:

    您参考的知识库文章以这种方式给出了您的答案...

    为了优化应用层的性能,Winsock 将数据缓冲区从应用程序发送调用复制到 Winsock 内核缓冲区。然后,堆栈使用自己的启发式算法(例如 Nagle 算法)来确定何时将数据包实际放入网络中。

    并且,设置 TCP_NODELAY 或 SO_SNDBUF=0 将禁用 Nagle 算法,如下所示,

    TCP_NODELAY 套接字选项用于禁用 Nagle 算法,以便将小数据包无延迟地传递到远程主机。

    您可以使用 SO_SNDBUF 选项更改分配给套接字的 Winsock 内核缓冲区的数量(默认为 8K)。如有必要,Winsock 可以缓冲远远超过 SO_SNDBUF 缓冲区大小。在大多数情况下,应用程序中的发送完成仅表示应用程序发送调用中的数据缓冲区被复制到 Winsock 内核缓冲区,并不表示数据已经到达网络介质。唯一的例外是通过将 SO_SNDBUF 设置为 0 来禁用 Winsock 缓冲


    阅读您下面的评论,我意识到您可能会感到困惑,因为设置 TCP_NODELAY 或设置 SO_SNDBUF=0 似乎都在做同样的事情。如果是这种情况,请注意 Nagle 仅适用于 TCP 流(将数据分段为数据包),而 SO_SNDBUF 也适用于 UDP 套接字。

    将 SO_SNDBUF 设置为零显式地停止所有输出缓冲,并为套接字上的每个“写入”尝试立即分派(至少在正常套接字实现中)。

    设置 TCP_NODELAY 将显式停止 TCP 套接字上的 Nagle 算法,尽管发送缓冲区可能可用并用于延迟调度(在向应用程序确认发送成功后)。

    【讨论】:

    • 还不清楚。它说使用 TCP_NODELAY 禁用它。最后突出显示的语句表示发送完成通知会延迟到实际发送数据。与禁用 Nagle 算法无关。
    • 发送完成也表明数据已经到达网络介质的“唯一例外”是当 SO_SNDBUF 设置为 0 时。这意味着在应用程序中,如果您想确认数据传送到网络线,您也可以将 SO_SNDBUF 设置为 0。这将强制立即调度到线。
    【解决方案2】:

    SO_SNDBUF 设置为 0 不会强制在线上立即发送。

    【讨论】:

      【解决方案3】:

      将 SO_SNDBUF 设置为零将不会隐式禁用 nagle; WSK 维护的 nagle 状态与缓冲区所在的位置无关。 有责任保持您发布的缓冲区有效,直到传输消耗它。

      【讨论】:

        猜你喜欢
        • 2019-05-10
        • 2015-09-16
        • 2012-03-29
        • 1970-01-01
        • 2014-07-11
        • 2012-03-25
        • 2020-08-07
        • 2017-02-08
        • 2013-04-24
        相关资源
        最近更新 更多