WCF:System.Net.SocketException - 通常只允许使用每个套接字地址(协议/网络地址/端口)

asy*_*ait 46 asp.net wcf socketexception

我有一个WCF服务和一个Web应用程序.Web应用程序以连续的方式调用此WCF服务,即轮询.在我们的生产环境中,我很少收到此错误.因为,这是一个内部活动,用户不知道何时抛出此错误.

无法连接到 http://localhost/QAService/Service.svc.TCP错误代码10048:通常只允许使用每个套接字地址(协议/网络地址/端口)127.0.0.1:80.---> System.Net.WebException:无法连接到远程服务器---> System.Net.Sockets.SocketException:通常只允许使用每个套接字地址(协议/网络地址/端口)127.0.0.1 :80

我在dev/qa环境中重现这种行为时遇到了麻烦.我确保在try..catch..finally块中关闭客户端连接.仍然不明白是什么导致了这个问题..谁知道这个?

注意:我已经看过这个问题,但似乎没有回答我的问题,所以不是重复的问题.

jri*_*sta 73

您正在重载TCP/IP堆栈.Windows(我认为实际上所有套接字堆栈)都有一个限制,即由于套接字在正常操作下如何关闭,可以快速打开的套接字数量.无论何时关闭套接字,它都会进入TIME_WAIT状态一段时间(IIRC为240秒).每次轮询时,套接字都会超出默认动态范围(我认为它大约有5000个动态端口在1024以上),每次轮询结束时,该特定套接字进入TIME_WAIT.如果您经常轮询,您将最终消耗所有可用端口,这将导致TCP错误10048.

通常,WCF会尝试通过池连接和类似的事情来避免此问题.通常情况下,内部服务不会通过互联网.我不确定是否有任何wsHttp绑定支持连接池,但netTcp绑定应该.我认为命名管道不会遇到这个问题.我不能说MSMQ绑定.

您可以使用两种解决方案来解决此问题.您可以增加动态端口范围,也可以减少TIME_WAIT的周期.前者可能是更安全的路径,但是如果你正在消耗极大量的套接字(这听起来不像你的情况),减少TIME_WAIT是一个更好的选择(或者两者兼而有之.)

更改动态端口范围

  1. 打开注册表.
  2. 打开HKLM\System\CurrentControlSet\Services\Tcpip\Parameters
  3. 编辑(或创建为DWORD)MaxUserPort值.
  4. 将其设置为更高的数字.(即65534)

更改TIME_WAIT延迟

  1. 打开注册表.
  2. 打开HKLM\System\CurrentControlSet\Services\Tcpip\Parameters
  3. 编辑(或创建为DWORD)TcpTimedWaitDelay.
  4. 将其设置为较低的数字.价值以秒为单位.(即60分钟延迟1分钟)

上述解决方案之一应该可以解决您的问题.如果它在更改端口范围后仍然存在,我会看到尝试增加轮询周期,以免频繁发生...这将使您有更多的余地来处理等待延迟的时间.作为最后的手段,我会改变等待延迟的时间.

  • 我可以查看一个计数器,看看现在有多少连接在使用? (3认同)
  • HKEY_LOCAL_MACHINE \系统\ CurrentControlSet \服务\ TCPIP \参数\ TcpTimedWaitDelay的 (2认同)

sti*_*mms 9

HttpClient虽然它实现了IDisposable是一个共享对象,但你应该尽可能地减少实例数量.您可以在应用程序的整个生命周期中只使用一个实例,而不是每个请求都有一个实例.

我在http://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/上写了很多文章.