插座"冲洗"通过暂时使无延迟 [英] Socket "Flush" by temporarily enabling NoDelay
问题描述
我在C#中的HTTP服务器的实现。 使用 AB 我发现了一个奇怪的性能问题。 每个请求了5毫秒保活关,但40毫秒,保活的!
I have an implementation of an HTTP server in C#. Using ab I discovered a weird performance issue. Each request took 5 ms with Keep-Alive Off but 40 ms with Keep-Alive on!
该testpage生成到一个字节[],它使用一个单一的socket.Send呼叫被发送的答复。
The testpage is generated into a single byte[] which get sent as reply using a single socket.Send call.
原因是,据我可以告诉在TCP堆栈使用Nagle算法。
The cause is as far as I can tell Nagle's algorithm used in the TCP stack.
到目前为止,我现在用的是无需等待在每个HTTP请求的高端物业服务。
So far I am using the NoDelay property in the end of every HTTP request served.
socket.NoDelay = true;
socket.NoDelay = false;
这确实解决了问题了。但我没有文档备份我的发现。
Which does solve the problem for now. But I have no documentation to backup my discovery.
这是在Linux /单系统测试。
This was tested on a linux/mono system.
有冲洗TCP连接的标准方式?
<一个href="http://stackoverflow.com/questions/1781766/paste-httpserver-and-slowdown-with-http-1-1-keep-alive-tested-with-httperf-and-a/1795352#1795352">This答案是解决同样的问题。这里的区别是,我希望只是暂时禁用该算法。
This answer is addressing the same issue. The difference here is that I am looking to only temporarily disabling the algorithm.
推荐答案
我测试了使用Wireshark。不幸的是,
I tested this with Wireshark. Unfortunately,
socket.NoDelay = true;
socket.NoDelay = false;
没有效果。同样,
has no effect. Similarly,
socket.NoDelay = true;
socket.Send(new byte[0]);
socket.NoDelay = false;
也没有任何影响。从观察到的行为,看来,无延迟
属性只影响下次调用发送
与非空缓冲区。换句话说,你必须无延迟
之前发送一些实际的数据会产生什么影响。
also has no effect. From observed behaviour, it appears that the NoDelay
property only affects the next call to Send
with a non-empty buffer. In other words, you have to send some actual data before NoDelay
will have any effect.
所以,我的结论是没有办法明确刷新插槽,如果你不想发送任何额外的数据。
Therefore, I conclude that there is no way to explicitly flush the socket if you don’t want to send any extra data.
不过,既然你正在编写一个HTTP服务器,你可以使用一些小技巧:
However, since you are writing an HTTP server, you may be able to use a few tricks:
- 对于使用
传输编码处理的请求:分块
,您可以将尾流的标志(在\ r \ N0 \ r \ñ\ r \ N
)使用无需等待= TRUE
。 - 如果您是从本地文件系统提供的文件,你就会知道文件结束的时候,所以你可以设置
无需等待= TRUE
刚刚发送的最后一块了。 - 对于使用
内容编码处理的请求:GZIP
,你可以设置无延迟=真正的结束
之前使用gzip流; gzip的流将前实际完成和关闭发送一些最后一位。
- For requests that are served using
Transfer-Encoding: chunked
, you can send the end-of-stream marker (the"\r\n0\r\n\r\n"
) withNoDelay = true
. - If you are serving a file from the local filesystem, you will know when the file ends, so you could set
NoDelay = true
just before sending the last chunk. - For requests that are served using
Content-Encoding: gzip
, you can setNoDelay = true
just before closing the gzip stream; the gzip stream will send some last bits before actually finishing and closing.
我当然要加上面的我的HTTP服务器现在:)
I’m certainly going to add the above to my HTTP server now :)
这篇关于插座&QUOT;冲洗&QUOT;通过暂时使无延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!