背景
我在C#中实现了HTTP服务器。
使用ab我发现了一个奇怪的性能问题。
关闭保持 Activity 状态时每个请求花费5毫秒,而打开保持 Activity 状态则花费40毫秒!
测试页生成为单个byte [],使用单个socket.Send调用将其作为答复发送。
据我所知,原因可能是TCP堆栈中使用的Nagle算法。
TCP刷新?
到目前为止,我在每个HTTP请求服务的末尾都使用NoDelay属性。

socket.NoDelay = true;
socket.NoDelay = false;
哪个确实可以解决问题。但是我没有文档来备份我的发现。
已在linux/mono系统上进行了测试。
是否存在刷新TCP连接的标准方法?
有关的
This answer正在解决相同的问题。此处的区别在于,我希望仅暂时禁用该算法。

最佳答案

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

  • 我当然要立即将以上内容添加到我的HTTP服务器中:)

    09-04 06:55