我正在使用一个商业应用程序,它抛出了一个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字节的数据包。但这到底是什么意思呢?

有两种可能,我不确定是哪一种,

连接正在关闭,但随后数据正在写入套接字,从而创建了上述异常。0#0仅仅意味着没有发送任何东西,因为套接字已经关闭。 连接仍然是打开的,并且正在发送一个零字节的数据包(即代码有一个错误),而0#0意味着一个零字节的数据包正在试图发送。

你怎么看?我猜这可能是不确定的,但也许有人见过这种东西?


当前回答

我也遇到了同样的问题,并最终设法解决了它。在我的例子中,客户端发送请求的端口没有与之绑定SSL证书。因此,我通过将SSL证书绑定到服务器端的端口来解决这个问题。一旦完成了这个操作,这个异常就消失了。

其他回答

我得到这个异常是因为实体中的循环引用。在实体中

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]到父属性。这样问题就解决了。

解决这个恼人问题的简单方法:

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

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

public DBEntities() 
        : base("name=DBEntities") 
    { 
        this.Configuration.ProxyCreationEnabled = false; // ADD THIS LINE!
    }

如果运行在。net 4.5.2服务中

对我来说,这个问题更加复杂,因为调用运行在. net 4.5.2服务中。我遵循了@willmaz的建议,但得到了一个新的错误。

在打开日志记录的情况下运行服务时,我看到与目标站点的握手将启动ok(并发送承载令牌),但在接下来处理Post调用的步骤中,它似乎会丢弃认证令牌,站点将以未经授权的方式回复。

解决方案

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

我在使用. net Framework 4.5时遇到了同样的问题。但是,当我将. net版本更新到4.7.2时,连接问题就解决了。也许这是由于安全协议支持的问题。

对于从流读取数据时出现此异常的任何人,这可能会有所帮助。我在这样的循环中读取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可能会出现问题。系统配置:

“Http。sys是IIS用来与客户端进行http通信的http协议栈。它有一个名为MinBytesPerSecond的定时器,负责在传输速率低于kb/sec阈值时终止连接。默认情况下,该阈值设置为240 kb/秒。”

这个问题在TFS开发团队的一篇旧博客文章中有描述,并特别关注IIS,但可能会为您指明正确的方向。它还提到了一个与此http相关的旧错误。Sys属性:link

如果您正在使用Azure应用程序服务,并且增加缓冲区大小并不能消除问题,请尝试扩展您的机器。您将被分配更多资源,包括连接带宽。