.NET:从 HTTP API 下载时如何发送 TCP Keep Alive 数据包?

Ail*_*n79 2 .net c# tcp httpclient

使用 .NET/C# 应用程序,我尝试从 HTTP API 下载数据。即使 HttpClient 实例的超时设置为 30 分钟,请求的超时速度也会更快。今天我了解到这是因为 .NET HttpClient 不发送任何 TCP Keep Alive 数据包。(这就是为什么我可以从 Chrome 中的 API 下载数据,正如 Wireshark 所证明的那样,Chrome 确实发送这些数据包,而 HttpClient 则不发送。)

这就是我希望从 API 获取 JSON 数据的方式:

this.httpclient = new HttpClient();
[...]
result = await this.httpclient.GetAsync(url);
Run Code Online (Sandbox Code Playgroud)

现在我做了一些研究,但我不知道如何发送这些保持活动 ping。HttpClient 似乎不支持它们。所以我的猜测是打开连接时需要在套接字上启用这些。有没有解决这个问题的方法,也许可以避免 HttpClient?我可以在套接字上启用 Keep-Alive ping 吗?这是需要通过操作系统启用的功能吗?

请注意:不是与 HTTP“Connection: Keep-Alive”标头您可以为 HttpClient 类启用此功能,但由于显而易见的原因,它不会触发任何 TCP Keep Alive 数据包。

编辑: Wireshark 中捕获的 Keep-Alive 数据包 当客户端发送这些 Keep-Alive 数据包时,请求始终有效,否则它们将失败。这可以通过使用不同的客户端/浏览器来重现。最好的例子:Postman Chrome 扩展确实会发送 Keep-Alive 数据包,因此请求有效。使用几乎相同的 Postman 独立客户端,请求会失败(或不返回任何数据),因为有趣的是,独立客户端不会发送任何可以使用 Wireshark 轻松检查的 Keep-Alive 数据包。

编辑:我找到了解决这个问题的一个非常简单的解决方案,请参阅下面的答案。

Ail*_*n79 5

所以现在我最终回答了我自己的问题,因为我刚刚找到了一个实际上有效的超级简单的解决方案:

this.httpclient = new HttpClient();
var sp = ServicePointManager.FindServicePoint(new Uri(url));
sp.SetTcpKeepAlive(true, 30000, 30000);
result = await this.httpclient.GetAsync(url);
Run Code Online (Sandbox Code Playgroud)

事实上我用过

var sp = ServicePointManager.FindServicePoint(new Uri(baseUrl));
Run Code Online (Sandbox Code Playgroud)

其中 baseUrl 是我通过 for 循环发送的所有请求的公共文档根。