远程主机强制关闭现有连接

时间:2010-04-06 00:54:22

标签: c# .net networking sockets

我正在使用一个商业应用程序,它正在抛出带有消息的SocketException,

  

远程主机强行关闭现有连接

客户端和服务器之间的套接字连接会发生这种情况。连接仍然存在,并且正在传输大量数据,但随后它将无法断开连接。

以前有人见过这个吗?原因是什么?我可以猜出一些原因,但也有什么方法可以在这段代码中添加更多内容以找出原因可能是什么?

欢迎任何意见/想法。

......最新......

我有一些.NET跟踪记录,

System.Net.Sockets Verbose: 0 : [8188] Socket#30180123::Send() DateTime=2010-04-07T20:49:48.6317500Z

System.Net.Sockets Error: 0 : [8188] Exception in the Socket#30180123::Send - An existing connection was forcibly closed by the remote host DateTime=2010-04-07T20:49:48.6317500Z 

System.Net.Sockets Verbose: 0 : [8188] Exiting Socket#30180123::Send() -> 0#0

根据日志记录的其他部分,我看到它说“0#0”表示正在发送长度为0字节的数据包。但这究竟意味着什么?

两种可能性中的一种是发生,我不确定是哪种,

1)连接正在关闭,但数据随后被写入套接字,从而产生上述异常。 0#0只表示没有发送任何内容,因为套接字已经关闭。

2)连接仍处于打开状态,正在发送一个零字节的数据包(即代码有错误),0#0表示正在尝试发送零字节数据包。

你觉得怎么样?我想这可能是不确定的,但也许其他人已经看到了这种事情?

13 个答案:

答案 0 :(得分:75)

这通常意味着远程端关闭连接(通常通过发送TCP / IP RST数据包)。如果您正在使用第三方应用程序,可能的原因是:

  • 您正在向表单发送格式错误的数据
  • 客户端和服务器之间的网络链接由于某种原因而下降
  • 您已触发第三方应用程序中导致其崩溃的错误
  • 第三方应用程序已耗尽系统资源

第一种情况可能就是发生了什么。

您可以启动Wireshark以查看线路上发生的确切情况,以缩小问题范围。

如果没有更具体的信息,这里的任何人都不可能真正帮助你。

答案 1 :(得分:36)

使用TLS 1.2解决了这个错误 你可以使用TLS 1.2强制你的应用程序(确保在调用你的服务之前执行它):

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 

另一种解决方案:
在本地计算机或服务器中启用强加密以使用TLS1.2,因为默认情况下它被禁用,因此仅使用TLS1.0。 要启用强加密,请使用管理员权限在PowerShell中执行这些命令:

Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord 

您需要重新启动计算机才能使这些更改生效。

答案 2 :(得分:25)

这不是代码中的错误。它来自.Net的Socket实现。如果您使用EndReceive的重载实现,如下所示,您将不会遇到此异常。

    SocketError errorCode;
    int nBytesRec = socket.EndReceive(ar, out errorCode);
    if (errorCode != SocketError.Success)
    {
        nBytesRec = 0;
    }

答案 3 :(得分:8)

解决这个常见烦人问题的简单方法:

只需转到“ .context.cs”文件(位于“* .edmx”文件下的“ .context.tt”下)。

然后,将此行添加到构造函数中:

public DBEntities() 
        : base("name=DBEntities") 
    { 
        this.Configuration.ProxyCreationEnabled = false; // ADD THIS LINE !
    }
希望这很有帮助。

答案 4 :(得分:8)

有同样的错误。实际上工作的情况是使用一些代理(在我的情况下是小提琴手)发送流量。将.NET框架从4.5.2更新为> = 4.6,现在一切正常。实际要求是:
new WebClient().DownloadData("URL");
例外是:

  

SocketException:现有连接被强制关闭   远程主机

答案 5 :(得分:1)

由于实体中的循环引用,我得到了这个例外。在实体中看起来像

public class Catalog
{
    public int Id { get; set; }
    public int ParentId { get; set; }
    public Catalog Parent { get; set; }
    public ICollection<Catalog> ChildCatalogs { get; set; }
}

我将[IgnoreDataMemberAttribute]添加到Parent属性中。这解决了这个问题。

答案 6 :(得分:0)

如果在.Net 4.5.2服务中运行

对我来说,这个问题更加复杂,因为该呼叫在.Net 4.5.2服务中运行。我遵循@willmaz的建议,但是遇到了一个新的错误。

在打开日志记录的情况下运行服务时,我查看了与目标站点的握手将启动ok(并发送承载令牌)的情况,但是在接下来的步骤中处理Post调用时,它似乎会删除auth令牌并该网站将回复Unauthorized

事实证明,服务池凭据没有更改TLS(?)的权限,当我将本地管理员帐户放入池中时,一切正常。

答案 7 :(得分:0)

我遇到了同样的问题,最终设法解决了。就我而言,客户端向其发送请求的端口没有绑定SSL证书。因此,我通过将SSL证书绑定到服务器端的端口来解决此问题。一旦完成,该异常就消失了。

答案 8 :(得分:0)

对于从流中读取数据时遇到此异常的任何人,这可能会有所帮助。在像这样的循环中读取HttpResponseMessage时遇到此异常:

using (var remoteStream = await response.Content.ReadAsStreamAsync())
using (var content = File.Create(DownloadPath))
{
    var buffer = new byte[1024];
    int read;

    while ((read = await remoteStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
    {
        await content.WriteAsync(buffer, 0, read);
        await content.FlushAsync();
    }
}

一段时间后,我发现罪魁祸首是缓冲区大小,它太小了,无法与我的弱Azure实例很好地配合使用。有用的是将代码更改为:

using (Stream remoteStream = await response.Content.ReadAsStreamAsync())
using (FileStream content = File.Create(DownloadPath))
{
    await remoteStream.CopyToAsync(content);
}

CopyTo()方法的默认缓冲区大小为81920。较大的缓冲区加速了该过程,并且错误立即停止,这很可能是因为总体下载速度提高了。但是为什么下载速度对防止此错误很重要?

由于下载速度下降到服务器配置为允许的最低阈值以下,因此您可能与服务器断开连接。例如,如果您要从中下载文件的应用程序托管在IIS上,则可能是http.sys配置出现问题:

“ Http.sys是IIS用于与客户端进行http通信的http协议栈。它具有一个称为MinBytesPerSecond的计时器,该计时器负责在其传输速率降至某些kb / sec阈值以下时终止连接。默认情况下,该阈值设置为240 kb / sec。”

此问题在TFS开发团队的旧博客中进行了描述,并且特别涉及IIS,但可能会为您指明正确的方向。它还提到了与此http.sys属性相关的旧错误:link

如果您使用的是Azure应用服务,并且增加缓冲区大小不能解决问题,请尝试扩大计算机规模。将为您分配更多资源,包括连接带宽。

答案 9 :(得分:0)

使用.NET Framework 4.5时遇到相同的问题。但是,当我将.NET版本更新为4.7.2时,连接问题已解决。也许是由于SecurityProtocol支持问题引起的。

答案 10 :(得分:0)

我在使用Microsoft sutdio for mssql时尝试连接到postgresql时遇到了这个问题:

答案 11 :(得分:-1)

当我尝试从枚举列中读取null的数据库中读取一行时,我得到了此异常,它无法将null映射到枚举值。

答案 12 :(得分:-1)

每当我没有在10秒内发送或接收数据时,我的CIP协议应用程序就会出现此错误。

这是由使用前向打开方法引起的。您可以通过使用其他方法来避免这种情况,或者安装保持前向打开连接的更新速率低于10秒。