我很难搞清楚.NET 4.0中的HttpWebRequest为每个请求创建套接字连接,但之后无法关闭套接字。 当我执行例如50个HttpWebRequests时,我在netstat中看到处于WAIT状态的50个TCP套接字连接。
我已经将代码减少到最低限度:
Dim webReq As HttpWebRequest
Dim webRes As HttpWebResponse
Dim webStream As IO.StreamReader
Dim _answer As String
webReq = System.Net.HttpWebRequest.Create(TextBox1.Text)
webReq.Timeout = 10000
webReq.Method = WebRequestMethods.Http.Get
webRes = webReq.GetResponse
webStream = New IO.StreamReader(webRes.GetResponseStream(), System.Text.Encoding.ASCII())
_answer = webStream.ReadToEnd
RichTextBox1.Text = _answer
webRes.Close()
webRes = Nothing
webReq = Nothing
任何想法,提示都很感激!
提前致谢
克里斯
答案 0 :(得分:2)
无论何时打开套接字并关闭它,它都会在完全关闭之前进入“TIME-WAIT”状态。此状态应防止后续tcp连接延迟接收延迟的tcp数据包。 我正在处理一个将数千个CGI请求发布到服务器的应用程序。问题是服务器使用HTTP / 1.0,这意味着每个请求打开一个新套接字并在交换数据后立即关闭它。 经过一段时间的数千个tcp连接,其中netstat显示在“TIME-WAIT”状态。插座,或更精确的端口,已经筋疲力尽。 Windows没有为新的CGI请求提供应用程序的新套接字。过了一会儿,所有的TIME-WAIT套接字都关闭了,应用程序可以继续通信。此问题源于服务器的HTTP / 1.0特性。
从Windows的角度来看,这个问题有两个“修复”。通过调整REGISTRY,您可以允许Windows管理超过默认的5000 tcp连接(我已经读取了一个很好的上限可以是20.000)。另一种选择是减少TIME-WAIT时间本身。这也可以通过调整REGISTRY来完成。这两个选项都不能解决我们庞大的套接字耗尽问题。
在最终的解决方案中,我们使用了一个名为“SO-LINGER”的TCP套接字选项。在创建端口时设置此选项允许跳过TCP套接字的TIME-WAIT状态。 请记住,这种状态存在是有原因的!跳过它是最后一个选项之一,适合我们的需求,因为我们通过套接字传输几个字节。在使用此选项之前,请考虑可能的影响。
该项目是在VB .NET 4.0中开发的。我用来创建套接字的代码发布在下面:
Private _plcAddress As String
Private _plcSocket As Socket
Private _endPoint As IPEndPoint
...
Dim myOpts As New LingerOption(True, 0)
Dim ipAddress As IPAddress = ipAddress.Parse(plcAddress)
_plcAddress = plcAddress
_plcSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP)
_plcSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, myOpts)
_endPoint = New IPEndPoint(IPAddress, 80)
...
答案 1 :(得分:0)
你的意思是'TIME_WAIT'吗?如果是这样,请完成你的50个请求,去喝咖啡,回到你的盒子里,用netstat重新检查。
关闭TCP套接字会执行终止握手并将套接字对象排队以进行释放。 TCP设计实际上不会释放套接字几分钟 - 即使在成功连接终端后,某些数据包仍可能通过慢速路由。因此,在任何此类剩余物死亡之前,不得将套接字重新分配给另一个连接。
RGDS, 马丁