WCF:套接字连接已中止

Posted

技术标签:

【中文标题】WCF:套接字连接已中止【英文标题】:WCF: The socket connection was aborted 【发布时间】:2011-04-28 18:52:59 【问题描述】:
CommunicationException was unhandled by user code
The socket connection was aborted. This could be caused by an error processing your message
or a receive timeout being exceeded by the remote host, or an underlying network resource
issue. Local socket timeout was '02:48:04.9840000'.

几个月来我一直在测试这个应用程序,并且在对其中一项服务进行小幅更改后刚刚看到这个错误。只有几秒钟,所以我认为这不是超时问题。

InnerException: System.IO.IOException : 读取操作失败,查看内部异常

(Inner) InnerException: System.Net.Sockets.SocketException - 现有连接被远程主机强行关闭。

非常感谢任何建议!

提前致谢

【问题讨论】:

我建议你调查一下远程主机关闭连接的原因。 好吧,当我调试它时,一切似乎都很好,但是当从管理器返回到代理(客户端)时,抛出异常。我想说更多的数据通过是允许的,但不会比平常更多的数据通过 您尝试过 WCF 跟踪吗? 你能为这个拉迪斯拉夫推荐一个好的资源吗? msdn.microsoft.com/en-us/library/ms733025.aspx 【参考方案1】:

通常,当对方没有完全关闭连接时,我会看到此错误。如果在客户端您有一个继承自 ClientBase<T> 的类,那么您应该在完成服务后调用 Close(实际上 ClientBase<T> 实现了 IDisposable,因此您可以使用 using 语句)。

如果您使用ChannelFactory<T> 来创建与服务的连接,则结果是一个实现合同但也实现ICommunicationObject 的代理;完成后,您应该致电Close

在服务端,情况不一样,会话(以及底层的套接字)由客户端管理。如果服务正在丢弃套接字,这很可能是错误的结果,在这种情况下,Music Magi 的建议是一个很好的建议。微软谈论如何处理这个here。

请注意,要清楚地了解正在发生的事情,您可能必须同时为客户端和服务设置跟踪。为了查看跟踪,您将使用SvcTraceViewer,它应该位于Program Files\Microsoft SDKs\Windows\v6.0A\binProgram Files\Microsoft SDKs\Windows\v7.0A\bin 文件夹中。如果您必须同时跟踪客户端和服务,您可以在SvcTraceViewer 中使用File / Add 菜单同时打开这两个文件。

【讨论】:

【参考方案2】:

您很可能遇到绑定中定义的 MaxReceivedMessageSize、MaxArrayLength、MaxStringContentLength 等配额问题。

您还可以查看行为中可用的 MaxItemsInObjectGraph 属性。

【讨论】:

【参考方案3】:

我经历了一些套接字连接由于不同的原因而中止,我觉得值得回答。

正如 Johann 指出的那样,除了在 MaxReceivedMessageSize、MaxArrayLength、MaxStringContentLength、MaxItemsInObjectGraph 中没有足够高的值...

检查以确保您正在序列化的类型可以很好地与 WCF 配合使用。例如,我遇到了同样的问题,但后来意识到我通过线路发送System.DBNull 导致服务中止。一旦我过滤掉了DBNull 对象,事情又开始工作了。

【讨论】:

【参考方案4】:

在我的例子中,向响应对象添加了一个枚举,但用于填充该对象的存储过程没有从数据库返回值。它正在返回其默认值(为零),这对于创建的枚举来说不是有效值。举个例子:

using System;

namespace Playground

    internal class Program
    
        private static void Main(string[] args)
        
            Console.WriteLine((int)new SomeResponse().Enum);
            Console.ReadLine();
        

        public enum SomeEnum
        
            Value1 = 1,
            Value2 = 2,
            Value3 = 3
        

        public class SomeResponse
        
            public SomeEnum Enum  get; set; 
        
    

您将看到枚举的值为零,即使没有枚举值为零。

如果您尝试从 WCF 调用返回 SomeResponse 对象并且它具有此状态,您最终会收到与问题中所述相同的错误。

【讨论】:

【参考方案5】:

在我的例子中,我在流上返回了一个带有 using 子句的 Stream。这在发送之前关闭了流并创建了连接中止错误。

【讨论】:

【参考方案6】:

在我的例子中,我们有两个系统 - remoteSystemclientSystem

两个系统都有用于身份验证的公共/私有证书。 每个系统都有自己的私钥和对等方的公钥。 客户端使用dev.clientSubsystem.acme 证书对自己进行身份验证

起初怀疑是防火墙,但通过测试消除了这一点

Test-NetConnection -Port 808 -ComputerName dev.remote-system.acme-corp.net-InformationLevel Detailed

事实证明,这个错误是当 clientSystem 配置为使用其私有证书 (dev.clientSubsystem.acme) 进行身份验证时,但证书不存在 - 或者在我们的例子中是引用了错误的证书进行身份验证。

<system.serviceModel>
   <client>
      <endpoint name="RemoteSystemService" address="net.tcp://dev.remote-system.acme-corp.net:808/service.svc" behaviorConfiguration="remoteSystemNetTcpBindingBehavior" binding="netTcpBinding" contract="AcmeCorp.RemoteSystem.IRemoteSystemService">
         <identity>
            <dns value="dev.remote-system.acme" />
         </identity>
      </endpoint>
   </client>
   <bindings>
      <netTcpBinding>
         <binding>
            <security mode="Transport">
               <transport clientCredentialType="Certificate" protectionLevel="EncryptAndSign" />
            </security>
         </binding>
      </netTcpBinding>
   </bindings>
   <behaviors>
      <endpointBehaviors>
         <behavior name="remoteSystemNetTcpBindingBehavior">
            <clientCredentials>
               <clientCertificate findValue="CN=dev.clientSubsystem.acme" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectDistinguishedName" />
               <serviceCertificate>
                  <authentication certificateValidationMode="PeerTrust" />
               </serviceCertificate>
            </clientCredentials>
         </behavior>
      </endpointBehaviors>
   </behaviors>
</system.serviceModel>

【讨论】:

以上是关于WCF:套接字连接已中止的主要内容,如果未能解决你的问题,请参考以下文章

(初学者)C#/WCF:套接字连接中止

套接字连接被中止 - CommunicationException

WCF常见问题

带有重复 AJAX 调用的 Django 关闭套接字错误 [WinError 10053] 已建立的连接被主机中的软件中止

工作组上的 WCF

***Error 然后 SocketException:软件导致连接中止:套接字写入错误 [重复]