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

hul*_*ist 5 .net c# tcp

背景

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

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

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

TCP Flush?

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

socket.NoDelay = true;
socket.NoDelay = false;
Run Code Online (Sandbox Code Playgroud)

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

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

有没有标准的方法来刷新TCP连接?

有关

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

Tim*_*mwi 6

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

socket.NoDelay = true;
socket.NoDelay = false;
Run Code Online (Sandbox Code Playgroud)

没有效果.同样的,

socket.NoDelay = true;
socket.Send(new byte[0]);
socket.NoDelay = false;
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

  • 如果我们只有[TCP Nagle flush](http://stackoverflow.com/questions/6726832/what-happened-to-the-tcp-nagle-flush)...... (3认同)