Как исправить это SocketException - PullRequest
0 голосов
/ 13 марта 2009

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

Ответы [ 2 ]

5 голосов
/ 13 марта 2009

Я думал, что socket.Close () позаботился об этом, но, думаю, нет. В этом случае вам нужно использовать:

socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

Подробнее о параметрах сокета можно прочитать здесь .

1 голос
/ 13 марта 2009

Это известная проблема в Windows, что даже если вы закрыли сокет, существует время ожидания, прежде чем ресурс вернется в ОС.

Существует способ вручную установить время ожидания для сокета в .NET, однако это может быть лучшим вариантом пересмотреть ваш дизайн, вместо того, чтобы оставить сокет слушателя открытым, вместо того, чтобы закрывать его, и вместо этого закрыть новый сокет, который создается во время Socket.Accept ();

...