静态 HttpClient 仍在创建 TIME_WAIT tcp 端口

2023-11-24

我在 .NET Framework(4.5.1+、4.6.1 和 4.7.2)中的 HttpClient 中遇到了一些有趣的行为。由于 TCP 端口使用率高的已知问题,我建议在工作中的项目中进行一些更改,以便在每次使用时不处理 HttpClient,请参阅https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/.

我调查了这些更改,以检查事情是否按预期工作,并发现我们仍然遇到与以前相同的 TIME_WAIT 端口。

为了确认我提出的更改是正确的,我向应用程序添加了一些额外的跟踪,以确认我在整个应用程序中使用相同的 HttpClient 实例。此后我使用了简单的测试应用程序(取自上面链接的 aspnetmonsters 站点)。

using System;
using System.Net.Http;

namespace ConsoleApplication
{
    public class Program
    {
        private static HttpClientHandler { UseDefaultCredentials = true };
        private static HttpClient Client = new HttpClient(handler);
        public static async Task Main(string[] args) 
        {
            Console.WriteLine("Starting connections");
            for(int i = 0; i<10; i++)
            {
                var result = await Client.GetAsync("http://localhost:51000");
                Console.WriteLine(result.StatusCode);
            }
            Console.WriteLine("Connections done");
            Console.ReadLine();
        }
    }
}

仅当使用 Windows 身份验证连接到 IIS 中托管的站点时,才会出现此问题。我可以通过将身份验证设置为匿名(问题消失)并返回到 Windows 身份验证(问题再次出现)来轻松重现该问题。

Windows 身份验证的问题似乎并不局限于提供商的范围。如果您使用 Negotiate 或 NTLM,也会遇到同样的问题。如果计算机只是工作站或域的一部分,也会出现此问题。

出于兴趣,我创建了一个 dotnet core 2.1.0 控制台应用程序,问题根本不存在并且按预期工作。

TLDR:有谁知道如何解决这个问题,或者它可能是一个错误?


简洁版本

如果要重用 NTLM 身份验证连接,请使用 .NET Core 2.1

长版

我很惊讶地发现,当使用 NTLM 身份验证时,“旧”HttpClient 确实为每个请求使用不同的连接。这不是一个错误 - 在 .NET Core 2.1 HttpClient 之前,它将使用 HttpWebRequest,它会在每次经过 NTLM 身份验证的调用后关闭连接。

这在文档中进行了描述HttpWebRequest.UnsafeAuthenticatedConnectionSharing可用于启用连接共享的属性:

该属性的默认值为 false,这会导致当前连接在请求完成后关闭。您的应用程序每次发出新请求时都必须执行身份验证序列。

如果此属性设置为 true,则用于检索响应的连接在执行身份验证后保持打开状态。在这种情况下,将此属性设置为 true 的其他请求可以使用该连接而无需重新进行身份验证。

风险在于:

如果用户 A 的连接已通过验证,则用户 B 可以重用 A 的连接;用户 B 的请求根据用户 A 的凭据得到满足。

如果人们了解风险和应用程序doesn't使用模拟,可以使用以下方式配置 HttpClient网络请求处理程序并设置不安全的身份验证连接共享, eg :

HttpClient _client;

public void InitTheClient()
{
    var handler=new WebRequestHandler
                { 
                    UseDefaultCredentials=true,
                    UnsafeAuthenticatedConnectionSharing =true
                };
    _client=new HttpClient(handler); 
}

网络请求处理程序doesn't暴露HttpWebRequest.ConnectionGroupName这将允许对连接进行分组,例如按 ID,因此它无法处理模拟。

.NET核心2.1

HttpClient 在 .NET Core 2.1 中被重写,并使用套接字、最小分配、连接池等实现所有 HTTP、网络功能。它还处理NTLM 质询/响应流程分开,因此可以使用相同的套接字连接来服务不同的经过身份验证的请求。

如果有人感兴趣,您可以跟踪从 HttpClient 到 SocketsHttpHanlder 到 HttpConnectionPoolManager 、 HttpConnectionPool、HttpConnection、AuthenticationHelper.NtAuth 的调用,然后返回 HttpConnection 以发送原始字节。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

静态 HttpClient 仍在创建 TIME_WAIT tcp 端口 的相关文章

随机推荐

  • 查找 CSS 未应用的规则

    我有一个很大的 CSS 样式表 大约 6500 行 有什么方法可以确定哪些规则不适用于给定页面 firefox 插件 Web 实用程序或其他东西 Thanks PD 使用 Firebug 我可以找到哪些规则适用 但我无法找到哪些规则不适用
  • 有人可以在休眠状态下向我解释一下@MapsId吗?

    有人可以向我解释一下吗 MapsId冬眠时 我很难理解它 如果能用一个例子来解释它 以及它最适用于哪种用例 那就太好了 这是一个很好的解释对象数据库 指定为 EmbeddedId 主键 EmbeddedId 主键内的属性或父实体的简单主键提
  • 在for循环中使用@ref来获取元素引用

    我试图在不同的地方获取同一对象的位置 其中 使用 javascript 函数 我应该得到不同的顶部位置 但这不是场景 脚本代码 Index razor代码 inject IJSRuntime jsRuntime div for int i
  • 列出目录中具有特定扩展名的所有文件

    假设我想列出所有php目录中的文件 包括子目录 我可以在 bash 中运行 ls l find name php type f 这样做的问题是 如果没有php文件 执行的命令是ls l 列出所有文件和目录 而不是没有 这是一个问题 因为我试
  • iPhone/桌面应用程序的相同代码库

    我有一个 iPhone iPad 应用程序 我想将其移植到 MacOSX 我的大多数目标 C 类只要不包含 UIKit 内容就应该可以正常工作 显然 界面会有所不同 在 Xcode 中执行此操作的最佳方法是什么 开始一个全新的项目 添加新目
  • 如何在按键时获得本地化字符?

    我需要得到本地化字符 on keypress事件 例如 在捷克语键盘上 我需要输入 而不是 5 个字符 键码 53 请参阅捷克语键盘布局 有没有其他方法来获取字符而不使用文本输入和读取值 换句话说 有什么方法可以从事件对象中获取符合当前用户
  • 如何显示从 axios 请求返回的图像(React)?

    我正在使用 React 开发一个谷歌地图项目 我为 onClick 处理程序分配以下方法 getStreetView lat lng let url https maps googleapis com maps api streetview
  • 如何在onKeyPress期间获取输入文本框的文本?

    我试图在用户输入文本时获取文本框中的文本 jsfiddle游乐场 function edValueKeyPress var edValue document getElementById edValue var s edValue valu
  • 如何从 docker 容器“avahi 浏览”?

    我正在运行一个基于 ubuntu 14 04 的容器 并且我需要能够使用avahi browse在里面 然而 env root 8faa2c44e53e opt cluster manager avahi browse a Failed t
  • PDO PHP bindValue 不起作用

    我知道这个问题已经被问了 1000 次了 但出于某种原因 我继续用头撞墙 这有效 sql SELECT a eventCode a eventTime a teamCode a playerCode b lastName b firstNa
  • 将 ImageView 中的图像保存到设备图库

    我正在尝试将图像从 ImageView 保存到设备库 我试过这段代码 代码编辑 URL url new URL getIntent getStringExtra imageURL File f new File url getPath ad
  • 为什么第二个 for 循环总是比第一个循环执行得快?

    我试图弄清楚 for 循环是否比 foreach 循环更快 并使用 System Diagnostics 类来计时任务 在运行测试时 我注意到我放在第一个循环的执行速度总是比最后一个循环慢 有人可以告诉我为什么会发生这种情况吗 我的代码如下
  • 我的 javascript 文件中的 Laravel 4 Blade 语法

    我的主页有一些内联 javascript 与一些刀片语法混合在一起 例如 它一直有效 直到我想将 javascript 移动到外部 file js 每当添加刀片语法时我都会出错 有没有办法可以在我的 javascript files js
  • 为什么在推导类型时会删除模板参数的限定符?

    在使用 Microsoft VisualStudio 2008 构建一个小示例程序时 我注意到传递给模板的类型推导有一个奇怪的事情 考虑这个例子 template
  • 在 C 中, (x==y==z) 的行为是否符合我的预期?

    我可以比较如下三个变量 而不是这样做if x y y z z x 如果所有三个变量具有相同的值 则应执行 if 语句 这些是布尔值 if debounceATnow debounceATlast debounceATlastlast deb
  • 在 Swing 中的组件顶部进行绘制?

    我有一个JPanel添加到JViewport 并且该面板还添加了几个其他面板 我正在尝试实现一种拖动选择 您可以通过拖动鼠标来选择多个组件 我面临的唯一问题是选择矩形被绘制在添加到主组件的组件后面JPanel 我怎样才能在它们上面画画 我的
  • Powershell 彩色目录列表在格式范围内不正确

    我从这里得到了这个彩色目录脚本http tasteofpowershell blogspot com 2009 02 get childitem dir results color coded html function ls regex
  • JPA 和 JSON 运算符本机查询

    我试图让这个查询在 JPA 中工作 SELECT FROM contrat WHERE contrat json gt nom hever 它完美地与postgresql但是当我将它与JPA集成时 出现以下错误 该位置 1 的参数不存在 M
  • 给定 N 个生成器,是否可以创建一个在并行进程中运行它们并生成这些生成器的 zip 的生成器?

    假设我有 N 个生成器gen 1 gen N其中每个都会产生相同数量的值 我想要一台发电机gen这样它就可以在 N 个并行进程中运行 gen 1 gen N 并产生 next gen 1 next gen 2 next gen N 这就是我
  • 静态 HttpClient 仍在创建 TIME_WAIT tcp 端口

    我在 NET Framework 4 5 1 4 6 1 和 4 7 2 中的 HttpClient 中遇到了一些有趣的行为 由于 TCP 端口使用率高的已知问题 我建议在工作中的项目中进行一些更改 以便在每次使用时不处理 HttpClie