gpt4 book ai didi

c# - WCF 服务停止工作 10054 WSAECONNRESET 连接被对等方重置

转载 作者:太空宇宙 更新时间:2023-11-03 12:56:09 25 4
gpt4 key购买 nike

我有两个 WCF 服务在我的计算机 (Windows 8) 的 Windows 窗体应用程序 (C#/.NET 4) 中运行:

首次服务:https://localhost:9002

二次服务:https://local_192-168-1-104.desktop.Company.com:9003

第一个服务在本地访问,第二个服务由本地网络中的其他计算机访问。主机:local_192-168-1-104.desktop.Company.com被DNS解析为ip:192.168.1.104,这是我的本地网络ip地址。

两个服务都使用 https,第一个使用 SelfSigned 证书,第二个使用证书:desktop.Company.com

问题 : 一段时间不活动后,第二个服务停止工作。

不记录任何异常,也不执行 WebServiceHost 的 Faulted()、UnknownMessageReceived()、Closing() 或 Closed() 事件。

如果我关闭应用程序并重新启动它,问题仍然存在。在这种错误情况下,WebServiceHost 的 State 属性为“Opened”,但服务没有响应。

如果我停止服务,重新配置服务(主题:配置证书服务 2),然后再次启动,问题会停止一段时间。

我使用以下方法测试 wcf 服务:

using (WebClient webClient = new WebClient())
{
webClient.DownloadDataCompleted += webClient_DownloadDataCompleted;
webClient.DownloadDataAsync(new Uri("https://local_192-168-1-104.desktop.Company.com:9003/Message/Test"));
}

我收到了这个异常(exception):

底层连接已关闭:发送时发生意外错误。
>> INNER EXCEPTION:
Message: An existing connection was forcibly closed by the remote host
Type: System.Net.Sockets.SocketException (System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
Source: System
TargetSite: Int32 EndReceive(System.IAsyncResult)
ErrorCode: 10054
StackTrace:
---------------------------
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
---------------------------

Windows 错误代码 10054 是:

对等方重置连接。

An existing connection was forcibly closed by the remote host. This normally results if the peer application on the remote host is suddenly stopped, the host is rebooted, the host or remote network interface is disabled, or the remote host uses a hard close (see setsockopt for more information on the SO_LINGER option on the remote socket). This error may also result if a connection was broken due to keep-alive activity detecting a failure while one or more operations are in progress. Operations that were in progress fail with WSAENETRESET. Subsequent operations fail with WSAECONNRESET.



我尝试禁用 Keep Alive,但问题仍然存在。

下面有更多详细信息:

配置证书服务 1
netsh http delete urlacl url=https://+:9002/
netsh http delete sslcert ipport=0.0.0.0:9002
netsh http add urlacl url=https://+:9002/ user=Everyone
makecert -sk RootCA -sky signature -pe -n CN=localhost -r -sr LocalMachine -ss Root certificate\CustomCertificate_MyCA.cer
makecert -sk server -sky exchange -pe -n CN=localhost -ir LocalMachine -is Root -ic certificate\CustomCertificate_MyCA.cer -sr LocalMachine -ss My certificate\CustomCertificate.cer
(install certificate in CertificateStore)
netsh http add sslcert ipport=0.0.0.0:9002 certhash=F3F40BF81AF0.... appid={00a1d32c-68bd-4693-a872-...}

启动服务1
var mainServiceHost = new Company.Library.WCF.JSONServiceHost("localhost", 9002, true);
mainServiceHost.Start(typeof(Service.Message), typeof(Service.IMessage), false);

配置证书服务 2
netsh http delete urlacl url=https://+:9002/
netsh http delete sslcert ipport=192.168.1.146:9003
netsh http add urlacl url=https://+:9003/ user=Everyone
(install certificate in CertificateStore)
netsh http add sslcert ipport=192.168.1.146:9003 certhash=1C36C9C... appid={00a1d32c-68bd-4693-a872-1473...}

启动服务2
var localServerServiceHost = new Company.Library.WCF.JSONServiceHost("local_192-168-1-104.desktop.Company.com", 9003, true);
localServerServiceHost.Start(typeof(Service.Message), typeof(Service.IMessage), false);

JSONServiceHost 类
public void Start(Type serviceType, Type implementedContract, bool keepAliveEnabled)
{
EndpointAddress endpoint = new EndpointAddress(Url);

CustomServiceBehavior serviceBehavior = new CustomServiceBehavior();
svcWebHost.Description.Behaviors.Add(serviceBehavior);

BindingElementCollection bindingElements;

WebHttpBinding binding = new WebHttpBinding(WebHttpSecurityMode.Transport);

bindingElements = binding.CreateBindingElements();
if (bindingElements != null)
{
var transport = bindingElements.Find<HttpsTransportBindingElement>();
if (transport != null)
transport.KeepAliveEnabled = keepAliveEnabled;
}

binding.ReaderQuotas.MaxArrayLength = int.MaxValue;
binding.ReaderQuotas.MaxBytesPerRead = int.MaxValue;
binding.ReaderQuotas.MaxDepth = int.MaxValue;
binding.ReaderQuotas.MaxNameTableCharCount = int.MaxValue;
binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
binding.MaxBufferSize = int.MaxValue;
binding.MaxBufferPoolSize = int.MaxValue;
binding.MaxReceivedMessageSize = int.MaxValue;

binding.SendTimeout = TimeSpan.FromMinutes(5);
binding.ReceiveTimeout = TimeSpan.FromMinutes(5);
binding.OpenTimeout = TimeSpan.FromMinutes(5);
binding.CloseTimeout = TimeSpan.FromMinutes(5);

ServiceEndpoint serviceEndpoint = svcWebHost.AddServiceEndpoint(implementedContract, binding, endpoint.Uri);

ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
svcWebHost.Description.Behaviors.Add(smb);

ServiceDebugBehavior sdb = svcWebHost.Description.Behaviors.Find<ServiceDebugBehavior>();
if (sdb != null)
sdb.IncludeExceptionDetailInFaults = true;

foreach (var operation in serviceEndpoint.Contract.Operations)
operation.Behaviors.Add(new CustomOperationBehavior());

svcWebHost.Open();
}

应用程序启动时执行的附加配置
private static void ConfigureGlobalServiceParameters()
{
System.Net.ServicePointManager.CheckCertificateRevocationList = false;
System.Net.ServicePointManager.DefaultConnectionLimit = int.MaxValue;
System.Net.ServicePointManager.DnsRefreshTimeout = -1;
System.Net.ServicePointManager.Expect100Continue = false;
System.Net.ServicePointManager.MaxServicePointIdleTime = 20 * 1000;
System.Net.ServicePointManager.MaxServicePoints = 10;
System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(delegate { return true; });
System.Net.ServicePointManager.UseNagleAlgorithm = false;
System.Net.ServicePointManager.SetTcpKeepAlive(false, 0, 0);
}

自定义端点行为
public class CustomEndpointBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}

public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
}

public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{
var customInspector = new CustomDispatchMessageInspector();
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(customInspector);
}

public void Validate(ServiceEndpoint endpoint)
{
}
}

自定义操作行为
public class CustomOperationBehavior : IOperationBehavior
{
public void AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}

public void ApplyClientBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.ClientOperation clientOperation)
{
}

public void ApplyDispatchBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.DispatchOperation dispatchOperation)
{
}

public void Validate(OperationDescription operationDescription)
{
}
}

自定义服务行为
public class CustomServiceBehavior : IServiceBehavior
{
public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}

public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
{
CustomEndpointBehavior endpointBehavior = new CustomEndpointBehavior();
foreach (var endpoint in serviceDescription.Endpoints)
endpoint.Behaviors.Add(endpointBehavior);
}

public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
{
}
}

谢谢!

最佳答案

我回到这个问题,终于找到了解决方案。

这不是 WCF 的问题,WCF 停止工作是因为证书与 Windows 端口的关联不起作用。

问题:

  • 您有证书(不是自签名证书);
  • 您可以使用以下命令将此证书与 Windows 端口相关联:“netsh http add sslcert”并在 WCF 或其他服务中使用它;
  • 重启后,或者系统长时间空闲,这个停止工作;

  • 后果:

    在 Windows 重新启动后,该服务停止在此端口中工作,并出现以下描述的行为:
  • 如果您尝试对 url 执行 Http 请求,您会收到以下错误:
    底层连接已关闭:发送时发生意外错误。
  • 如果您尝试再次将证书关联到端口,请使用以下命令:

  • 命令: netsh http add sslcert ipport=192.168.1.146:9003 certhash=1C36.. appid={00a1..}
    您收到此错误:

    SSL Certificate add failed, Error: 1312 A specified logon session does not exist. It may already have been terminated.


  • 如果您尝试导出证书,请使用:

  • 命令: certutil -exportPFX -p "[password]" My [cert_SerialNumber] "c:\temp\desktop.pfx" NoChain
    您收到此错误:

    Private key is NOT exportable Encryption test passed CertUtil: -exportPFX command FAILED: 0x8009000b (-2146893813 NTE_BAD_KEY_STATE) CertUtil: Key not valid for use in specified state.



    如何重现所有配置过程:
  • 从 .pfx 获取证书:

  • 代码: X509Certificate2 certificate = new X509Certificate2(certPath, password);
  • 将证书证书添加到 CertificateStore(StoreName:“MY”,StoreLocation:LocalMachine):

    X509Store store = new X509Store(storeName.My, StoreLocation.LocalMachine);
    store.Open(OpenFlags.ReadWrite);
    store.Add(证书);
    商店.关闭();
  • 将证书附加到端口:

  • 命令: netsh http add sslcert ipport=192.168.1.146:9003 certhash=1C36C... appid={00a..} clientcertnegotiation=enable
  • 配置 windows 防火墙以允许访问端口:

  • (我这样做是因为我正在从本地网络中的另一台计算机访问 WCF)

    如何手动解决问题:

    在这篇文章中:
    http://www.hanselman.com/blog/WorkingWithSSLAtDevelopmentTimeIsEasierWithIISExpress.aspx

    有这个解决方案:

    I think by moving the self signed cert from Personal to Trusted Root CA directory causes a problem that SSL stops working after developers reboot their machines. (Don't know how it happens, but it does happen consistently.) I finally get around this issue by export and re-import the self-signed cert into the trusted root directory (instead of simply drag it over). Now my self-signed cert is considered and I don't need to REINSTALL/REPAIR IIS Express every time I reboot the machine.



    神奇的是,您不需要从个人证书存储中导出证书,并在根目录中导入证书。您只需要在 windows 重启前手动导出证书,windows 重启后问题不会发生。

    如何使用命令行解决问题:

    在配置过程之后,在第一次 Windows 重新启动之前,执行以下命令:
  • 将证书导入“个人”证书存储:

  • 命令: certutil -f -p "[password]" -importpfx My "c:\temp\cert.pfx"
  • 使用此导出证书:

  • 命令: certutil -exportPFX -p "[password]" My [certificate_Serial_Number] "c:\temp\cert2.pfx" NoChain
    有值(value)的信息:
  • 列出安装在 Windows 本地计算机证书存储中的证书:
  • 开始/运行:mmc.exe
  • 文件/添加/删除管理单元...
  • 在可用的管理单元下,选择“证书”,然后选择“本地计算机”并按添加。
  • 使用命令“netsh http add sslcert”
  • 列出与端口关联的证书

    命令: certutil -store "My"
  • 删除证书与端口的关联:

  • 命令: netsh http delete sslcert ipport=192.168.1.104:9003
  • certutil 引用:

  • https://technet.microsoft.com/en-us/library/cc732443.aspx
  • 网络引用:

  • https://msdn.microsoft.com/en-us/library/windows/desktop/cc307220(v=vs.85).aspx

    关于c# - WCF 服务停止工作 10054 WSAECONNRESET 连接被对等方重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33784058/

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