Что происходит с сокетом при приостановке/возобновлении в окнах

У меня есть приложение С#.net4, которое прослушивает сокет, используя BeginReceiveFrom и EndRecieveFrom. Все работает как ожидается, пока я не заставлю машину спать, а затем возобновить.

В этот момент EndReceieveFrom выполняет и генерирует исключение (не может получить доступ к удаленному объекту). Похоже, что гнездо расположено, когда машина приостановлена, но я не уверен, как с этим справиться.

Предполагаю ли я, что все сокеты были удалены и воссоздают их все с нуля? У меня проблемы с отслеживанием точной проблемы, так как удаленная отладка также прерывается при приостановке/возобновлении.

Ответ 1

То, что происходит во время приостановки/возобновления, очень сильно зависит от вашего оборудования и настройки сети. Если ваша сетевая карта не отключена во время приостановки, а приостановка короткая, открытые соединения выживут приостановить/возобновить работу без каких-либо проблем (открыть TCP-соединения можно таймаутом на другом конце курса).

Однако, если ваш сетевой адаптер отключен во время сна, или это адаптер USB, который отключается, поскольку он подключен к отключенному концентратору или ваш компьютер получает новый IP-адрес от DHCP или ваш беспроводной адаптер снова подключается к другой точке доступа и т.д., тогда все текущие соединения будут удалены, слуховые сокеты уже не будут действительными и т.д.

Это значение не для сна/возобновления. Сетевые интерфейсы могут появиться и спуститься в любой момент, и ваш код должен справиться с этим. Вы можете легко имитировать это с помощью сетевого адаптера USB, например. вытащите его из своего компьютера, и ваш код должен его обработать.

Ответ 2

У меня были аналогичные проблемы с suspend/resume и сокетами (в .NET 4 и Windows 8, но я подозреваю, что не ограничился ими). ​​

В частности, у меня было приложение сокета-клиента, которое только получало данные. Чтение было сделано через BeginReceive с обратным вызовом. Код в обратном вызове обрабатывает типичные случаи сбоя (например, удаленный сервер закрывает соединение либо изящно, либо нет).

Когда клиентская машина перешла на спящий режим (и это, вероятно, относится к новому режиму быстрого запуска Windows 8, который действительно является своего рода спящим/спящим режимом), сервер закроет соединение через несколько секунд. Когда клиент проснулся, но вызов async read call-back не вызывался (что я ожидал бы, так как он должен вызываться, когда сокет имеет условие ошибки/закрывается в дополнение к тому, когда есть данные). Я явно добавил код на таймер к клиенту, чтобы периодически проверять это условие и восстанавливать его, но даже здесь (и используя комбинацию опроса, доступного и подключенного, чтобы проверить, было ли соединение вставлено) сокет на стороне клиента. STILL появился быть подключенным, поэтому код восстановления никогда не запускался. Я думаю, что если бы я попытался отправить данные, я бы получил ошибку, но, как я сказал, это было строго односторонним.

Решение, которое я закончил, заключалось в обнаружении возобновления из состояния сна и закрытии и восстановлении моих соединений сокетов, когда это произошло. Существует довольно много способов обнаружения резюме; в моем случае я писал службу Windows, поэтому я мог бы просто переопределить метод ServiceBase.OnPowerEvent.