Как изящно закрыть сокет с сервера - PullRequest
4 голосов
/ 21 октября 2011

На стороне сервера я пытаюсь изящно закрыть подключенный сокет. Я знаю, правильная последовательность событий на сокете должна быть:

  1. Отключение сокета с опцией SocketShutdown.Send

  2. цикл / ожидание, пока получение сокета вернется с 0 байтами

  3. розетка Закрыть

У меня есть несколько вопросов:

  1. что если Socket.Receive никогда не вернется (с 0 байтами)? мы застрянем, пытаясь закрыть сокет навсегда?

  2. всякий раз, когда я вызываю Close на сервере, Клиент всегда получает исключение «существующее соединение было принудительно закрыто удаленным хостом» на их конце. как я могу уведомить клиента об этом закрытии "изящно"?

  3. на сервере, если я использую вызовы Async Begin / EndReceive, всякий раз, когда я вызываю Close в сокете, это ВСЕГДА приводит к исключению ObjectDisposedException в потоке Begin / EndReceive. Нет ли способа закрыть сокет без возникновения этого исключения?

1 Ответ

2 голосов
/ 21 октября 2011
  1. Протокол TCP гарантирует, что сокет в конце концов закроется, если узел не разрешит ему закрыться.В этом случае вы должны ждать вечно или сдаваться, что угодно.

  2. Если вы закроете сокет после получения возврата, равного нулю, этого не произойдет.Если это так, ваш код, вероятно, делает что-то не так.

  3. Вы не можете освободить ресурс, когда асинхронная операция использует или может использовать его.Вместо того, чтобы звонить близко, вызовите выключение.Не закрывайте, пока не закончите на 100% с ресурсом.

...