在阅读this文章时,我有一个疑问。
据我所知,在传输小数据的同时,Nagle算法默认启用,可以合并小数据包。这导致在传输之前缓存一些数据。我相信Winsock内核缓冲区是缓存发生的地方。如果我错了,请纠正我。
这是否意味着如果使用SO_SNDBUF选项将Winsock内核缓冲区设置为零,是否会禁用Nagle算法?
如果没有,那么WINSOCK在哪里缓存小数据?
答案 0 :(得分: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算法,尽管发送缓冲区可用并用于延迟分派(在向应用程序确认发送成功之后)。
答案 1 :(得分:0)
SO_SNDBUF设置为0不会强制立即发送电线。
答案 2 :(得分:0)
将SO_SNDBUF设置为零将不隐式禁用nagle;由WSK维护的nagle状态与缓冲区所在的位置无关。你的责任是保持你发布的缓冲区有效,直到传输消耗它为止。