HttpWebRequest在TIME WAIT中保持套接字

时间:2011-05-31 09:58:50

标签: .net vb.net httpwebrequest

我很难搞清楚.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

任何想法,提示都很感激!

提前致谢

克里斯

2 个答案:

答案 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, 马丁