Вопрос

У меня есть цикл, который открывает сокет, действует на сокет, затем закрывает сокет и перезапускается. Однако на второй итерации я получаю 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 ();

scroll top