【问题标题】:WCF: The socket connection was abortedWCF:套接字连接已中止
【发布时间】: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 跟踪吗?
  • 你能为这个拉迪斯拉夫推荐一个好的资源吗?

标签: c# wcf service


【解决方案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>
            

            【讨论】:

              猜你喜欢
              • 2019-05-05
              • 1970-01-01
              • 1970-01-01
              • 2019-12-28
              • 1970-01-01
              • 2011-07-09
              • 1970-01-01
              • 2014-11-22
              • 1970-01-01
              相关资源
              最近更新 更多