3

这篇文章的时候,我有一个疑问。

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

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

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

4

3 回答 3

5

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

为了优化应用层的性能,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 算法,尽管发送缓冲区可能可用并用于延迟调度(在向应用程序确认发送成功后)。

于 2009-06-19T11:58:52.083 回答
0

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

于 2009-09-08T23:27:09.167 回答
0

Setting SO_SNDBUF to zero will not implicitly disable nagle; the nagle state maintained by the WSK is independent of where the buffer is located. It's your responsibility to keep the buffers you post valid till the transport consumes it.

于 2010-03-04T04:49:19.287 回答