.NET 6部署Windows Server无法连接WCF服务问题排查
WCF客户端在.NET 6/.NET Core部署到Windows Server 2019失败问题排查
问题概述
通过「添加WCF服务引用」创建的客户端,配置自定义SSL客户端证书后,本地运行的.NET 6/.NET Core 3.1版本可正常工作,但部署到Windows Server 2019服务器后出现连接中止错误(SocketException 10053),仅.NET Framework 4.7.2版本能正常运行。
客户端核心代码
using ConsoleAppFramework.MyServiceReference; using System; using System.Security.Cryptography.X509Certificates; using System.ServiceModel.Security; using System.Threading.Tasks; namespace ConsoleAppFramework { internal class Program { static async Task Main(string[] args) { SoapServicesClient client = new SoapServicesClient(); client.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(@"C:\My-Client-Cert.p12", "pass"); client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication() { CertificateValidationMode = X509CertificateValidationMode.None, RevocationMode = X509RevocationMode.NoCheck }; client.Open(); var res = await client.loginStaticAsync(Array.Empty<contextEntry>(), new userInfoRequestBean() { username = "user", password = "pass" }); client.Close(); Console.WriteLine(res.@return.sessionId); } } }
错误堆栈
Unhandled exception. System.ServiceModel.CommunicationException: An error occurred while sending the request. ---> System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.IO.IOException: Unable to read data from the transport connection: An established connection was aborted by the software in your host machine.. ---> System.Net.Sockets.SocketException (10053): An established connection was aborted by the software in your host machine. --- End of inner exception stack trace --- at System.Net.Security.SslStream.<FillBufferAsync>g__InternalFillBufferAsync|215_0[TReadAdapter](TReadAdapter adap, ValueTask`1 task, Int32 min, Int32 initial) at System.Net.Security.SslStream.ReadAsyncInternal[TReadAdapter](TReadAdapter adapter, Memory`1 buffer) at System.Net.Http.HttpConnection.FillAsync() at System.Net.Http.HttpConnection.ReadNextResponseHeaderLineAsync(Boolean foldedHeadersAllowed) at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken) --- End of inner exception stack trace --- at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.AuthenticationHelper.SendWithNtAuthAsync(HttpRequestMessage request, Uri authUri, ICredentials credentials, Boolean isProxyAuth, HttpConnection connection, HttpConnectionPool connectionPool, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(HttpConnection connection, HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.AuthenticationHelper.SendWithAuthAsync(HttpRequestMessage request, Uri authUri, ICredentials credentials, Boolean preAuthenticate, Boolean isProxyAuth, Boolean doRequestAuth, HttpConnectionPool pool, CancellationToken cancellationToken) at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.DecompressionHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts) at System.ServiceModel.Channels.HttpChannelFactory`1.HttpClientRequestChannel.HttpClientChannelAsyncRequest.SendRequestAsync(Message message, TimeoutHelper timeoutHelper) --- End of inner exception stack trace --- at ConsoleAppCore3_1.Program.Main(String[] args) in C:\Users\......\Program.cs:line 45 at ConsoleAppCore3_1.Program.<Main>(String[] args)
.NET Framework 4.7.2与.NET 6 WCF客户端的核心差异
- HTTP底层实现:.NET Framework依赖
System.Net.HttpWebRequest,.NET Core/.NET 6改用System.Net.Http.HttpClient,SSL/TLS握手逻辑、配置方式存在明显差异。 - 证书加载规则:.NET Framework对证书文件权限要求宽松,且兼容旧版证书存储逻辑;.NET Core/.NET 6加载PKCS#12(.p12)证书时默认不导出私钥,且对文件/存储读取权限校验更严格。
- SSL/TLS协议支持:.NET Framework默认继承系统SSL配置,.NET Core/.NET 6默认仅启用TLS 1.2/1.3,若WCF服务仅支持旧协议(如TLS 1.0/1.1)会直接握手失败。
- 代理处理逻辑:.NET Framework自动继承系统代理设置,.NET Core/.NET 6需显式配置代理参数。
针对Windows Server 2019部署问题的解决方案
1. 调整证书加载方式
方式一:导入证书到Windows存储
将.p12证书导入Windows Server 2019的「本地计算机-个人」存储,通过证书指纹加载,避免文件权限问题:
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine); store.Open(OpenFlags.ReadOnly); var certs = store.Certificates.Find(X509FindType.FindByThumbprint, "你的证书指纹", false); if (certs.Count > 0) { client.ClientCredentials.ClientCertificate.Certificate = certs[0]; } store.Close();
注意:需确保运行客户端的账户(如应用池账户、本地系统账户)有读取证书存储的权限。
方式二:修改证书加载参数
加载.p12时显式指定私钥可导出、使用机器密钥集,适配服务器部署场景:
client.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2( @"C:\My-Client-Cert.p12", "pass", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet );
2. 显式配置SSL/TLS协议
若WCF服务不支持TLS 1.2/1.3,强制指定兼容协议:
// 在创建WCF客户端前添加 System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12 | System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls;
3. 检查服务器环境配置
- 确认Windows Server 2019防火墙允许客户端访问WCF服务端口(通常为443);
- 若服务器使用代理,需在客户端显式配置代理:
var httpClientHandler = new HttpClientHandler { Proxy = new WebProxy("http://代理地址:端口"), UseProxy = true }; // 将handler关联到WCF绑定(需自定义绑定配置)
4. 启用WCF跟踪日志排查
添加配置生成详细日志,定位握手失败具体原因:
<!-- 写入app.config或appsettings.json对应配置节点 --> <system.diagnostics> <sources> <source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true"> <listeners> <add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="c:\logs\WcfTrace.svclog" /> </listeners> </source> </sources> </system.diagnostics>
内容的提问来源于stack exchange,提问作者dev-masih
相关产品推荐
相关产品推荐

