На странице .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;
Сокет извлекается через сеанс и используется позже, а затем уничтожается:
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();
I 'мы пробовали различные комбинации флагов, такие как Linger
, ReuseAddress
, ExclusiveAddressUse
и значения для Listen
backlog, но ничего не меняется.
Важное примечание: без опции ReuseAddress
сокетв TIME_WAIT
как показано netstat -ano
.Когда я использую ReuseAddress
, гнездо застревает в CLOSE_WAIT
.
Я полностью осведомлен о последствиях : есть ли способ программно уменьшить интервалы CLOSE_WAIT или TIME_WAIT для конкретного сокета, не касаясь реестра?
Iмне интересно, забываю ли я что-то при попытке утилизировать розетку ...