gpt4 book ai didi

c# - 通过临时启用 NoDelay 套接字 "Flush"

转载 作者:可可西里 更新时间:2023-11-01 02:32:01 30 4
gpt4 key购买 nike

背景

我有一个用 C# 实现的 HTTP 服务器。使用ab我发现了一个奇怪的性能问题。每个请求在 Keep-Alive 关闭时花费 5 毫秒,但在 Keep-Alive 打开时花费 40 毫秒!

测试页生成为单个 byte[],使用单个 socket.Send 调用作为回复发送。

据我所知,原因是 TCP 堆栈中使用的 Nagle 算法。

TCP 同花顺?

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

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
  • 如果您从本地文件系统提供文件,您将知道文件何时结束,因此您可以在发送最后一个 block 之前设置 NoDelay = true
  • 对于使用 Content-Encoding: gzip 服务的请求,您可以在关闭 gzip 流之前设置 NoDelay = true; gzip 流将在实际完成和关闭之前发送一些最后的位。

我现在当然要将以上内容添加到我的 HTTP 服务器:)

关于c# - 通过临时启用 NoDelay 套接字 "Flush",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5523565/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com