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\bin
或Program 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】:在我的例子中,我们有两个系统 - remoteSystem
和 clientSystem
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:套接字连接已中止的主要内容,如果未能解决你的问题,请参考以下文章
套接字连接被中止 - CommunicationException
带有重复 AJAX 调用的 Django 关闭套接字错误 [WinError 10053] 已建立的连接被主机中的软件中止