В настоящее время я работаю над серверным приложением на C++. Моими главными вдохновителями являются эти примеры:
Пример программы порта завершения ввода-вывода IPv4/IPv6
Мое приложение сильно похоже на эти (socketobj, packageobj,...).
В целом у меня приложение работает без проблем. Единственные вещи, которые до сих пор вызывают у меня проблемы, это полуоткрытые соединения.
Моя стратегия для этого такова: я проверяю каждого подключенного клиента за определенный период времени и подсчитываю «счетчик бездействия». Если происходит одно завершение, я сбрасываю этот таймер. Если счетчик Idle становится слишком большим, я устанавливаю логическое значение, чтобы другие потоки не публиковали операции, а затем вызываю closesocket()
.
Мое предположение заключалось в том, что теперь сокет закрыт, ожидающие операции завершатся (может быть, не мгновенно, а через некоторое время). Это также поведение, описанное в документации MSDN (подсказки, второй абзац). Мне это нужно, потому что только после завершения всех операций я могу освободить ресурсы.
Короче говоря: это не мой случай. Я провел несколько тестов с моим приложением testclient и отладкой cout и точек останова и обнаружил, что ожидающие операции для закрытых сокетов не завершаются (даже после ожидания 10 минут). Я также уже пробовал с вызовом shutdown()
перед closesocket()
, и оба не возвращали ошибок.
Что я делаю неправильно? Это случается с кем-то еще? Документация MSDN неверна? Какие есть альтернативы?
Сейчас я подумываю о функции "задержки" или о явной отмене каждой операции с помощью функции CancelIoEx()
Изменить: (спасибо за ответы)
Вчера вечером я добавил связанный список для каждого sockedobj, чтобы хранить per io obj ожидающих операций. С этим я попробовал функцию CancelIOEx()
. Функция вернула 0, а GetLastError()
вернула ERROR_NOT_FOUND для большинства операций.
Безопасно ли в этом случае просто освобождать Io Obj?
Я также обнаружил, что это происходит чаще, когда я запускаю свое серверное приложение и клиентское приложение на одном компьютере. Время от времени случается, что сервер не может завершить операции записи. Я думал, что это происходит из-за того, что буфер приема на стороне клиента заполняется. (Клиентская сторона не перестает получать данные!).
Отрезанный код следует как можно скорее.
WSASend()
можно опубликовать, но он никогда не будет завершен. Как я могу улучшить тест? - person Woife   schedule 13.10.2017ERROR_NOT_FOUND
, вероятно, означает, что в рассматриваемых сокетах нет ожидающих операций ввода-вывода. Что, вероятно, означает, что либо Windows, либо ваш код удалил исходные уведомления о завершении, гораздо более вероятно, что это ваш код. - person Harry Johnston   schedule 13.10.2017