我正在使用一个商业应用程序,该应用程序抛出 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
表示正在尝试发送一个零字节的数据包.
你觉得怎么样?我想这可能还没有定论,但也许其他人也见过这种东西?
I am working with a commercial application which is throwing a SocketException with the message,
An existing connection was forcibly closed by the remote host
This happens with a socket connection between client and server. The connection is alive and well, and heaps of data is being transferred, but it then becomes disconnected out of nowhere.
Has anybody seen this before? What could the causes be? I can kind of guess a few causes, but also is there any way to add more into this code to work out what the cause could be?
Any comments / ideas are welcome.
... The latest ...
I have some logging from some .NET tracing,
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
Based on other parts of the logging I have seen the fact that it says 0#0
means a packet of 0 bytes length is being sent. But what does that really mean?
One of two possibilities is occurring, and I am not sure which,
-
The connection is being closed, but data is then being written to the socket, thus creating the exception above. The 0#0
simply means that nothing was sent because the socket was already closed.
-
The connection is still open, and a packet of zero bytes is being sent (i.e. the code has a bug) and the 0#0
means that a packet of zero bytes is trying to be sent.
What do you reckon? It might be inconclusive I guess, but perhaps someone else has seen this kind of thing?
发布评论
评论(22)
这通常意味着远程端关闭了连接(通常通过发送 TCP/IP
RST
数据包)。如果您使用第三方应用程序,可能的原因是:很可能是第一种情况正在发生。
您可以启动 Wireshark 来准确查看线路上发生的情况,从而缩小问题范围。
如果没有更具体的信息,这里的任何人都不太可能真正为您提供帮助。
This generally means that the remote side closed the connection (usually by sending a TCP/IP
RST
packet). If you're working with a third-party application, the likely causes are:It's likely that the first case is what's happening.
You can fire up Wireshark to see exactly what is happening on the wire to narrow down the problem.
Without more specific information, it's unlikely that anyone here can really help you much.
使用 TLS 1.2 解决了此错误。
您可以通过此强制应用程序使用 TLS 1.2(确保在调用您的服务之前执行它):
另一个解决方案:
在本地计算机或服务器中启用强加密才能使用 TLS1.2,因为默认情况下它被禁用,因此仅使用 TLS1.0。
要启用强加密,请使用管理员权限在 PowerShell 中执行以下命令:
您需要重新启动计算机才能使这些更改生效。
Using TLS 1.2 solved this error.
You can force your application using TLS 1.2 with this (make sure to execute it before calling your service):
Another solution :
Enable strong cryptography in your local machine or server in order to use TLS1.2 because by default it is disabled so only TLS1.0 is used.
To enable strong cryptography , execute these commande in PowerShell with admin privileges :
You need to reboot your computer for these changes to take effect.
这不是您的代码中的错误。它来自.Net 的 Socket 实现。如果您使用如下所示的 EndReceive 的重载实现,您将不会收到此异常。
This is not a bug in your code. It is coming from .Net's Socket implementation. If you use the overloaded implementation of EndReceive as below you will not get this exception.
有同样的错误。实际上,如果使用某些代理(在我的例子中是提琴手)发送流量,则可以正常工作。将 .NET 框架从 4.5.2 更新到 >=4.6,现在一切正常。实际请求是:
new WebClient().DownloadData("URL");
例外的是:
Had the same bug. Actually worked in case the traffic was sent using some proxy (fiddler in my case). Updated .NET framework from 4.5.2 to >=4.6 and now everything works fine. The actual request was:
new WebClient().DownloadData("URL");
The exception was:
对于这个常见的恼人问题的简单解决方案:
只需转到“.context.cs”文件(位于“.context.tt”下,该文件位于“*.edmx”文件下)。
然后,将此行添加到您的构造函数中:
Simple solution for this common annoying issue:
Just go to your ".context.cs" file (located under ".context.tt" which located under your "*.edmx" file).
Then, add this line to your constructor:
由于实体中的循环引用,我遇到了此异常。在看起来像
我将 [IgnoreDataMemberAttribute] 添加到 Parent 属性的实体中。这解决了问题。
I've got this exception because of circular reference in entity.In entity that look like
I added [IgnoreDataMemberAttribute] to the Parent property. And that solved the problem.
如果在 .Net 4.5.2 服务中运行
对我来说,问题变得更加复杂,因为调用是在 .Net 4.5.2 服务中运行。我遵循了 @willmaz 的建议,但遇到了新的错误。
在打开日志记录的情况下运行服务时,我发现与目标站点的握手将正常启动(并发送不记名令牌),但在处理 Post 调用的后续步骤中,它似乎会删除身份验证令牌,并且站点将回复
未经授权
。解决方案
事实证明,服务池凭据没有更改 TLS 的权限(?),当我将本地管理员帐户放入池中时,一切正常。
If Running In A .Net 4.5.2 Service
For me the issue was compounded because the call was running in a .Net 4.5.2 service. I followed @willmaz suggestion but got a new error.
In running the service with logging turned on, I viewed the handshaking with the target site would initiate ok (and send the bearer token) but on the following step to process the Post call, it would seem to drop the auth token and the site would reply with
Unauthorized
.Solution
It turned out that the service pool credentials did not have rights to change TLS (?) and when I put in my local admin account into the pool, it all worked.
我遇到了同样的问题并最终解决了它。就我而言,客户端发送请求的端口没有绑定 SSL 证书。因此,我通过将 SSL 证书绑定到服务器端的端口来解决该问题。一旦完成,这个异常就消失了。
I had the same issue and managed to resolve it eventually. In my case, the port that the client sends the request to did not have a SSL cert binding to it. So I fixed the issue by binding a SSL cert to the port on the server side. Once that was done, this exception went away.
对于任何在从流中读取数据时遇到此异常的人来说,这可能会有所帮助。在这样的循环中读取 HttpResponseMessage 时,我遇到了这个异常:
一段时间后,我发现罪魁祸首是缓冲区大小,它太小了,不能很好地与我的弱 Azure 实例配合使用。有用的是将代码更改为:
CopyTo() 方法的默认缓冲区大小为 81920。更大的缓冲区加快了进程,错误立即停止,很可能是因为整体下载速度增加了。但为什么下载速度对于防止此错误很重要呢?
由于下载速度低于服务器配置允许的最低阈值,您可能会与服务器断开连接。例如,如果您下载文件的应用程序托管在 IIS 上,则可能是 http.sys 配置出现问题:
“Http.sys 是 IIS 用于与客户端执行 http 通信的 http 协议栈 计时器,负责在传输速率低于某个 kb/秒阈值时终止连接。默认情况下,该阈值设置为 240 kb/秒。”
它有一个名为 MinBytesPerSecond的 来自 TFS 开发团队的旧博文,特别关注 IIS,但可能会为您指明正确的方向。它还提到了与此 http.sys 属性相关的旧错误: 链接
如果您使用的是 Azure应用程序服务和增加缓冲区大小并不能解决问题,还可以尝试扩展您的计算机。您将被分配更多资源,包括连接带宽。
For anyone getting this exception while reading data from the stream, this may help. I was getting this exception when reading the HttpResponseMessage in a loop like this:
After some time I found out the culprit was the buffer size, which was too small and didn't play well with my weak Azure instance. What helped was to change the code to:
CopyTo() method has a default buffer size of 81920. The bigger buffer sped up the process and the errors stopped immediately, most likely because the overall download speeds increased. But why would download speed matter in preventing this error?
It is possible that you get disconnected from the server because the download speeds drop below minimum threshold the server is configured to allow. For example, in case the application you are downloading the file from is hosted on IIS, it can be a problem with http.sys configuration:
"Http.sys is the http protocol stack that IIS uses to perform http communication with clients. It has a timer called MinBytesPerSecond that is responsible for killing a connection if its transfer rate drops below some kb/sec threshold. By default, that threshold is set to 240 kb/sec."
The issue is described in this old blogpost from TFS development team and concerns IIS specifically, but may point you in a right direction. It also mentions an old bug related to this http.sys attribute: link
In case you are using Azure app services and increasing the buffer size does not eliminate the problem, try to scale up your machine as well. You will be allocated more resources including connection bandwidth.
我在使用 .NET Framework 4.5 时遇到了同样的问题。但是,当我将 .NET 版本更新到 4.7.2 时,连接问题得到了解决。也许这是由于 SecurityProtocol 支持问题。
I got the same issue while using .NET Framework 4.5. However, when I update the .NET version to 4.7.2 connection issue was resolved. Maybe this is due to SecurityProtocol support issue.
对我来说,这是因为我尝试发送电子邮件的应用服务器未添加到我们公司的 SMTP 服务器的允许列表中。
我只需为该应用服务器输入 SMTP 访问请求。
这就是基础设施团队添加的方式(我自己不知道如何执行这些步骤,但他们是这么说的):
For me, it was because the app server I was trying to send email from was not added to our company's SMTP server's allowed list.
I just had to put in SMTP access request for that app server.
This is how it was added by the infrastructure team (I don't know how to do these steps myself but this is what they said they did):
发生此错误的另一种可能性是,如果您多次尝试使用无效凭据连接到第三方服务器,并且 Fail2ban 等系统正在阻止您的 IP 地址。
Yet another possibility for this error to occur is if you tried to connect to a third-party server with invalid credentials too many times and a system like Fail2ban is blocking your IP address.
我试图使用 GO 客户端连接到 MQTT 代理,
代理地址以
地址 + 端口
或tcp://address:port
形式给出。示例: ❌
表示您希望建立未加密的连接。
要通过 TLS 请求 MQTT,请使用
ssl
、tls
、mqtts
、mqtt+ssl
或tcps 之一
。示例: ✅
I was trying to connect to the MQTT broker using the GO client,
broker address was given as
address + port
, ortcp://address:port
Example: ❌
which indicates that you wish to establish an unencrypted connection.
To request MQTT over TLS use one of
ssl
,tls
,mqtts
,mqtt+ssl
ortcps
.Example: ✅
就我而言,启用 IIS 服务器和然后重新启动并再次检查。
In my case, enable the IIS server & then restart and check again.
我们正在使用 SpringBoot 服务。我们的restTemplate 代码如下所示:
在为restTemplate 设置ReadTimeout 之后,我们所有的调用都失败了。我们增加了时间,我们的问题得到了解决。
We are using a SpringBoot service. Our restTemplate code looks like below:
All our call were failing after the ReadTimeout set for the restTemplate. We increased the time, and our issue was resolved.
我有时也遇到这个错误。增加服务器内存解决了我的问题。请确保您的服务器有足够的内存
I was getting this error sometimes too. Increasing the server memory solved my problem. please make sure you have enough memory on your server
有时这可能是 IIS 问题。如果您创建了新的自签名证书,则: 打开 IIS 管理器,确保您已在 IIS 中的每个绑定中更新了新的 ssl 证书名称。即(右键单击 -> 编辑绑定 -> https[编辑 -> 添加新的 ssl])
Sometimes this could be IIS issue. If you have created a new self signed certificate than: Open IIS manager, make sure you have updated the new ssl certificate name in each of the bindings in IIS. i.e (right click -> edit bindings -> https[edit->add new ssl])
尽管我不推荐它,但解决此问题的另一种快速而简单的方法是删除此邮件服务的依赖注入实现,并在每次调用它时实例化它。
Although I do not recommend it, another quick and easy way to solve this is to remove your dependency injection implementation of this mail service and instantiate it each time you call it.
当我返回包含 DateTime 属性的复杂类型时,我遇到了此异常。我的服务器使用 .Net 4.8.1,我的客户端使用 .Net 6.0
现在,我将数据类型更改为字符串以使其正常工作。我不知道如何更改微软的默认序列化。
另一个解决方案是不返回复杂类型,而是返回序列化的 json 字符串,您可以在其中选择格式。
I had this exception when I returned a complex type that contained DateTime properties. My server uses .Net 4.8.1 and my client uses .Net 6.0
For now I changed the datatype to string in order to make it work. I don't know how to change the default serialization from microsoft.
Another solution would be to not to return the complex type but a serialized json string, where you can chose the format.
通过添加解决:
solved by adding :
我在调用 Firebase 服务器时随机收到此错误,大约 1/10 次,并且无法在 Postman 中重现该错误。我的 C# 代码出了问题。经过一系列的尝试和错误,最终发现最可能的原因是重复调用
new HttpClient()
而不是重用它。许多消息来源都说不要这样做,但从未解释原因。我认为这篇文章可能会解释为什么它一开始似乎有效,但会在意想不到的时候中断: https://www.aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/I was getting this error randomly when calling a Firebase server, about 1/10 times, and could not reproduce it in Postman. So something was up with my C# code. After a bunch of trial and error finally found the most likely cause was repeatedly calling
new HttpClient()
instead of reusing it. Many sources say not to do it, but never explained why. I think this article might explain why it seems to work at first but will break at unexpected times: https://www.aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/每当我在 10 秒内没有发送或接收数据时,我的 CIP 协议应用程序就会发生此错误。
这是由于使用前向打开方法造成的。您可以通过使用其他方法来避免这种情况,或者安装低于 10 秒的更新速率来维持前向开放连接。
This error occurred in my application with the CIP-protocol whenever I didn't Send or received data in less than 10s.
This was caused by the use of the forward open method. You can avoid this by working with an other method, or to install an update rate of less the 10s that maintain your forward-open-connection.