closesocket () не завершает ожидающие операции IOCP

В настоящее время я работаю над серверным приложением на C ++. Мое главное вдохновение — эти примеры:

Пример Windows SDK IOCP

Пример программы сервера портов ввода / вывода IPv4 / IPv6

Мое приложение сильно похоже на это (socketobj, packageobj, …).

В общем, мое приложение работает без проблем. Единственное, что до сих пор доставляет мне неприятности — это полуоткрытые связи.

Моя стратегия заключается в следующем: я проверяю каждого подключенного клиента за определенный период времени и подсчитываю «счетчик простоя». Если происходит одно завершение, я сбрасываю этот таймер. Если значение счетчика Idle становится слишком высоким, я устанавливаю логическое значение, чтобы другие потоки не публиковали операции, а затем вызываю closesocket(),

Я предположил, что теперь сокет закрыт, ожидающие операции будут завершены (возможно, не сразу, а через некоторое время). Это также поведение, описанное в документации MSDN (подсказки, второй абзац). Мне это нужно, потому что только после завершения всех операций я могу освободить ресурсы.

Короче говоря: это не так для меня. Я провел несколько тестов с моим приложением testclient и отладкой cout и точки останова и обнаружил, что незавершенные операции для закрытых сокетов не завершаются (даже после ожидания 10 минут). Я тоже уже пробовал с shutdown() позвонить до closesocket()и оба не вернули ошибку.

Что я делаю неправильно? Это случается с кем-то еще? Документация MSDN неверна? Какие есть альтернативы?

В настоящее время я думаю о «задержке» функциональности, или отменить каждую операцию явно с помощью CancelIoEx() функция

Редактировать: (Спасибо за ваши ответы)

Вчера вечером я добавил цепочечный список для каждого sockedobj для хранения каждого объекта ожидающих операций. С этим я попробовал CancelIOEx() функция. Функция вернула 0 и GetLastError() возвращенный ОШИБКА НЕ НАЙДЕНА для большинства операций.

Тогда безопасно ли в этом случае просто освободить per Io Obj?

Я также обнаружил, что это происходит чаще, когда я запускаю свое серверное приложение и клиентское приложение на одном компьютере. Время от времени случается, что сервер не может завершить операции записи. Я думал, что это происходит из-за того, что клиентский приемный буфер становится полным. (Клиентская сторона не прекращает получать данные!).

Отрезанный код следует как можно скорее.

0

Решение

  • Параметр «задержаться» может использоваться для сброса соединения, но таким образом вы (а) потеряете данные и (б) осуществите сброс на одноранговый узел, что может привести к его ужасу.
  • Если вы думаете о положительном тайм-ауте, это не очень помогает.
  • Выключение для чтения должно прервать операции чтения, но завершение для записи ставится в очередь только после ожидающих записей, поэтому это не помогает вообще.
  • Если ожидающие записи являются проблемой, а не завершением, их придется отменить.
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]