Как исправить это SocketException
-
22-07-2019 - |
Вопрос
У меня есть цикл, который открывает сокет, действует на сокет, затем закрывает сокет и перезапускается.
Однако на второй итерации я получаю SocketException
, разрешено только одно использование каждого адреса сокета (протокол / сетевой адрес / порт).
Однако сокет должен быть закрыт, netstat -a
не показывает, что я слушаю этот порт или что-то еще. Код, который выдает исключение:
_bindedLocalSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_bindedLocalSocket.Bind(new IPEndPoint(Util.ChannelProfileToListeningAddress(_profile), _profile.ListenPort));
_bindedLocalSocket.Listen(30);
_bindedLocalSocket.BeginAccept(new AsyncCallback(OnRequested), null);
Однако я думаю, что виновником является не тот код, как раз перед тем, как я доберусь до этого кода, и прежде чем я попытаюсь закрыть соединение, я получаю это:
An existing connection was forcibly closed by the remote host at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult) at Poderosa.PortForwarding.SynchronizedSocket.EndReceive(IAsyncResult ar) at Poderosa.PortForwarding.Channel.OnSocketData(IAsyncResult result)
После того, как я закрою программу и снова запустю ее, она сможет нормально установить первое соединение, а второе - точно так же (SocketException). Кто-нибудь знает, как я могу это исправить?
Решение
Я думал, что socket.Close () позаботился об этом, но, думаю, нет. В этом случае вам нужно использовать:
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
Подробнее о параметрах сокетов можно прочитать здесь а>. р>
Другие советы
Это известная проблема в Windows, что даже если вы закрыли сокет, существует время ожидания, прежде чем ресурс будет возвращен в ОС. Р>
Существует способ вручную установить время ожидания для сокета в .NET, однако может оказаться лучшим вариантом вернуться к дизайну, вместо того, чтобы оставить сокет слушателя открытым, а не закрывать его, и вместо этого закрыть новый сокет, который создается во время Socket.Accept ();