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

时间:2011-04-02 13:55:43

标签: c# .net tcp

背景

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

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

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

TCP Flush?

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

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

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

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

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

相关

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

4 个答案:

答案 0 :(得分:6)

我用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服务器中:)

答案 1 :(得分:2)

如果您知道要发送的数据长度,则设置entrypoint: .docker/app/sh/entry-point.sh command: php-fpm 将使套接字立即发送数据,以下是一个有效的代码示例:

SendBufferSize

答案 2 :(得分:1)

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

如何构建您的回复以及如何发送回复?

答案 3 :(得分:-3)

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

不要禁用nagle。

  

Nagle TCP / IP算法是   旨在避免小问题   数据包,称为tinygrams,速度很慢   网络。算法说a   TCP / IP连接只能有一个   杰出的小部分,没有   但得到了承认。定义   “小”的变化但通常是   定义为“小于段   大小“在以太网上大约1500   字节。

请看这里:Disabling TCP/IP Nagle Algorithm Improves Speed on Slow Nets