通过暂时启用NoDelay来套接“刷新”

背景

我在C#中实现了HTTP服务器。 使用ab我发现了一个奇怪的性能问题。 保持活动关闭时,每个请求需要5毫秒,而保持活动状态则需要40毫秒!

测试页生成单个字节[],使用单个套接字作为回复发送。发送调用。

原因是我可以告诉Nrab在TCP堆栈中使用的算法。

TCP Flush?

到目前为止,我在每个服务的HTTP请求的末尾使用NoDelay属性。

socket.NoDelay = true; socket.NoDelay = false; 

现在哪个解决了这个问题。 但我没有备份我的发现的文件。

这是在linux / mono系统上测试的。

是否有标准的方式来刷新TCP连接?

有关

这个答案正在解决同样的问题。 这里的不同之处在于我希望暂时禁用该算法。

我用Wireshark测试了这个。 不幸,

 socket.NoDelay = true; socket.NoDelay = false; 

没有效果。 同样的,

 socket.NoDelay = true; socket.Send(new byte[0]); socket.NoDelay = false; 

也没有效果。 从观察到的行为来看,似乎NoDelay属性仅影响下一次使用非空缓冲区调用Send 。 换句话说,在NoDelay产生任何影响之前,您必须发送一些实际数据。

因此,我得出结论,如果您不想发送任何额外数据,则无法显式刷新套接字。

但是,由于您正在编写HTTP服务器,因此您可以使用一些技巧:

  • 对于使用Transfer-Encoding: chunked提供的请求,您可以使用NoDelay = true发送流结束标记( "\r\n0\r\n\r\n" )。
  • 如果您从本地文件系统提供文件,您将知道文件何时结束,因此您可以在发送最后一个块之前设置NoDelay = true
  • 对于使用Content-Encoding: gzip提供的请求,您可以在关闭gzip流之前设置NoDelay = true ; gzip流将在实际完成和关闭之前发送一些最后的位。

我现在肯定要将上面的内容添加到我的 HTTP服务器:)

自己编写了一个非常受欢迎的Web服务器后,我认为Nagle algortihm不是你真正的问题。

你如何建立自己的回答以及如何发送回复?

在TCP中没有冲洗这样的东西。 TCP是一种基于流的协议,用于对数据进行分组/取消分组/拆分/连接。 通过禁用nagle,它只会减少频率。

不要禁用nagle。

Nagle TCP / IP算法旨在避免在慢速网络上出现小数据包(称为tinygrams)的问题。 该算法表明TCP / IP连接只能有一个尚未确认的未完成的小段。 “小”的定义各不相同,但通常定义为“小于段大小”,在以太网上大约为1500字节。

请看这里: 禁用TCP / IP Nagle算法提高慢速网络的速度