猿问

以编程方式减少 TIME_WAIT 或 CLOSE_WAIT

在一个.aspx页面中,我需要将一个套接字绑定到一个端口,使用它,然后处理它。它第一次工作,但第二次访问该页面时出现以下异常:


[Exception in bind: System.Net.Sockets.SocketException (0x80004005): Only one usage of each socket 

 address (protocol/network address/port) is normally permitted

at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, 

 SocketAddress socketAddress)

at System.Net.Sockets.Socket.Bind(EndPoint localEP)

[...]

这是代码,异常触发错误。请注意 Accept() 块在我的场景中是完全可以接受的。


IPAddress ipAddress = IPAddress.Parse(ip);

Socket s1 = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

IPEndPoint ep = new IPEndPoint(ipAddress, port);

try {

    s1.Bind(ep);

} catch(Exception ex) {

    HttpContext.Current.Response.Write("[Exception in bind: "+ ex + "\n");

    return;

}

s1.Listen(32);

// block until there's a connection

Socket s2 = s1.Accept();

// save for later

Session["s1"] = s1;

Session["s2"] = s2;

套接字通过 Session 检索并稍后使用,并销毁:


Socket s1 = Session["s1"] as Socket;

Socket s2 = Session["s2"] as Socket;


// ... use the socket ...


// cleanup

s2.Shutdown(SocketShutdown.Both);

s2.Disconnect(true);

s2.Close();

s2.Dispose();

s1.Shutdown(SocketShutdown.Both);

s1.Disconnect(true);

s1.Close();

s1.Dispose();

我试过标志,如的各种组合Linger,ReuseAddress,ExclusiveAddressUse对于和值Listen积压,但没有改变。


重要提示:没有ReuseAddress插座连接器处于选项TIME_WAIT如图netstat -ano。当我使用时ReuseAddress,插座卡在CLOSE_WAIT.


我完全了解其中的含义:有没有办法以编程方式减少特定套接字的 CLOSE_WAIT 或 TIME_WAIT 间隔而无需触摸注册表?


我想知道我在尝试处理套接字时是否忘记了什么......


慕娘9325324
浏览 299回答 1
1回答

交互式爱情

事实证明,利用 Session 对象并不理想。第一次使用后,该端口将保持打开状态,根据显示的 PID netstat,IIS Worker 将拥有它。因此,似乎不可能调用Close()它。解决方案是在以下之后关闭服务器套接字(s1在我的示例中)Accept:[...]s1.Listen(32);// block until there's a connectionSocket s2 = s1.Accept();// *close the server socket*s1.Close();// only save s2 for laterSession["s2"] = s2;然后只使用s2,例如:// ...later onSocket s1 = Session["s1"] as Socket;try {    while ((bytesRead = s1.Receive(receiveBuffer)) > 0 ) {        byte[] received = new byte[bytesRead];        Array.Copy(receiveBuffer, received , bytesRead);        Response.BinaryWrite(received);    }} catch(Exception ex){[...]先前的解决方案使“清理”变得不必要。
随时随地看视频慕课网APP
我要回答