В настоящее время я работаю над серверным приложением на C ++. Мое главное вдохновение — эти примеры:
Пример программы сервера портов ввода / вывода IPv4 / IPv6
Мое приложение сильно похоже на это (socketobj, packageobj, …).
В общем, мое приложение работает без проблем. Единственное, что до сих пор доставляет мне неприятности — это полуоткрытые связи.
Моя стратегия заключается в следующем: я проверяю каждого подключенного клиента за определенный период времени и подсчитываю «счетчик простоя». Если происходит одно завершение, я сбрасываю этот таймер. Если значение счетчика Idle становится слишком высоким, я устанавливаю логическое значение, чтобы другие потоки не публиковали операции, а затем вызываю closesocket()
,
Я предположил, что теперь сокет закрыт, ожидающие операции будут завершены (возможно, не сразу, а через некоторое время). Это также поведение, описанное в документации MSDN (подсказки, второй абзац). Мне это нужно, потому что только после завершения всех операций я могу освободить ресурсы.
Короче говоря: это не так для меня. Я провел несколько тестов с моим приложением testclient и отладкой cout и точки останова и обнаружил, что незавершенные операции для закрытых сокетов не завершаются (даже после ожидания 10 минут). Я тоже уже пробовал с shutdown()
позвонить до closesocket()
и оба не вернули ошибку.
Что я делаю неправильно? Это случается с кем-то еще? Документация MSDN неверна? Какие есть альтернативы?
В настоящее время я думаю о «задержке» функциональности, или отменить каждую операцию явно с помощью CancelIoEx()
функция
Редактировать: (Спасибо за ваши ответы)
Вчера вечером я добавил цепочечный список для каждого sockedobj для хранения каждого объекта ожидающих операций. С этим я попробовал CancelIOEx()
функция. Функция вернула 0 и GetLastError()
возвращенный ОШИБКА НЕ НАЙДЕНА для большинства операций.
Тогда безопасно ли в этом случае просто освободить per Io Obj?
Я также обнаружил, что это происходит чаще, когда я запускаю свое серверное приложение и клиентское приложение на одном компьютере. Время от времени случается, что сервер не может завершить операции записи. Я думал, что это происходит из-за того, что клиентский приемный буфер становится полным. (Клиентская сторона не прекращает получать данные!).
Отрезанный код следует как можно скорее.
Других решений пока нет …