.NET 8 HttpClient在Windows Server 2019生产环境连接被强制关闭求助
问题背景
测试代码如下:
try { ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true; Console.WriteLine($"Started"); HttpClient cl = new HttpClient(); cl.DefaultRequestHeaders.Add("Connection", "keep-alive"); var response = cl.GetStringAsync("https://google.com").Result; Console.WriteLine(response); // ParsersV2(); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } Console.Read();
运行时抛出错误:Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host,仅Windows Server 2019生产服务器出现该问题,同版本测试服务器、Windows 2008、Ubuntu等环境均正常,Chrome和PowerShell可正常请求目标地址。
排查与解决步骤
检查TLS加密套件配置
生产服务器可能存在加密套件限制,导致与谷歌的TLS握手失败。打开gpedit.msc,导航到计算机配置>管理模板>网络>SSL配置设置>SSL加密套件顺序,确认配置的套件是否包含谷歌支持的TLS 1.2/1.3套件(比如TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384等)。可将测试服务器的加密套件导出后导入生产服务器对比配置。验证系统代理设置
尽管网络环境相同,生产服务器可能存在不同的代理配置。检查Internet选项>连接>局域网设置,确认是否启用了代理,同时检查代码中是否有未显式配置的代理(HttpClient默认使用系统代理)。可尝试在代码中禁用代理:HttpClientHandler handler = new HttpClientHandler { UseProxy = false }; HttpClient cl = new HttpClient(handler);安装Windows Server 2019最新TLS相关补丁
部分旧版本的Windows Server 2019存在TLS握手的兼容性问题,安装最新的累积更新(尤其是KB4577586及后续补丁),修复Schannel组件的已知bug。排查防火墙/终端安全软件
生产服务器的防火墙或EDR/XDR软件可能拦截了.NET程序的出站TLS连接。临时关闭相关安全软件测试,或添加.NET程序(如你的exe)到允许列表,同时检查防火墙是否允许443端口的出站流量(重点检查是否针对特定进程限制)。优化HttpClient的使用方式
原代码中未正确释放HttpClient资源,且同步调用.Result可能导致连接池异常。修改代码为:using (HttpClientHandler handler = new HttpClientHandler()) { handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true; using (HttpClient cl = new HttpClient(handler)) { cl.DefaultRequestHeaders.Connection.Clear(); cl.DefaultRequestHeaders.ConnectionClose = false; var response = await cl.GetStringAsync("https://google.com"); Console.WriteLine(response); } }同时避免手动添加
Connection: keep-alive,HttpClient默认已处理连接复用。启用Schannel日志排查握手细节
在注册表中启用Schannel日志:- 打开
regedit,导航到HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\EventLogging - 将
LoggingLevel设置为0x00000003(记录错误和警告) - 重启服务器后重新运行测试代码,查看
事件查看器>Windows日志>系统中的Schannel事件,定位TLS握手失败的具体原因(如证书验证、套件不匹配等)
- 打开
内容的提问来源于stack exchange,提问作者Sergey

