背景
我在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服务器中:)