插座"冲洗"通过暂时使无延迟 [英] Socket "Flush" by temporarily enabling NoDelay

查看:158
本文介绍了插座"冲洗"通过暂时使无延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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") with NoDelay = 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 set NoDelay = 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆