Windows: TCP / IP: принудительное закрытие соединения: избегать утечек памяти на уровне ядра / пользователя - PullRequest
0 голосов
/ 10 сентября 2011

Вопрос к специалистам по сетевому программированию Windows.

Когда я использую псевдокод, подобный этому:

reconnect:
    s = socket(...);
    // more code...

read_reply:
    recv(...);
    // merge received data
    if(high_level_protocol_error) {
        // whoops, there was a deviation from protocol, like overflow
        // need to reset connection and discard data right now!
        closesocket(s);
        goto reconnect;
    }

Отключает ли ядро ​​ядро ​​и освобождает ли все данные, "физически" полученные от NIC(поскольку он уже должен быть там, в памяти ядра, ожидая, пока пользовательский уровень прочитает его с помощью recv ()), когда я закрою сокет ()?Ну, это логично, так как данные больше не связаны ни с каким внутренним объектом, верно?

Потому что я действительно не хочу тратить неизвестное количество времени на чистое отключение, такое как " call recv () довозвращает ошибку".Это не имеет смысла: что, если он никогда не вернет ошибку, скажем, сервер продолжает отправлять данные вечно и не закрывает соединение, но это плохое поведение?

Мне интересно об этом, так как я нехочу, чтобы мое приложение вызывало утечки памяти в любом месте.Является ли этот способ принудительного сброса соединения, который по-прежнему ожидается, для отправки неизвестного объема данных правильным?

// необязательное дополнение к вопросу: если этот метод считается правильным для окон,Можно ли считать его правильным (с изменением closesocket() на close()) для UNIX-совместимой ОС?

Ответы [ 2 ]

1 голос
/ 10 сентября 2011

Драйверы ядра в Windows (или любой другой ОС), включая tcpip.sys, должны предотвращать утечки памяти при любых обстоятельствах, независимо от того, что вы делаете в пользовательском режиме. Я думаю, что разработчики наметили возможные состояния, включая состояния ошибок, чтобы убедиться, что ресурсы не просочились. Что касается пользовательского режима, я не совсем уверен, но я не думаю, что ресурсы просочились в ваш процесс.

Сокеты - это просто файловые объекты в Windows. Когда вы закрываете последний дескриптор файла, менеджер ввода-вывода отправляет сообщение IRP_MJ_CLEANUP драйверу, которому принадлежит файл, для очистки ресурсов, связанных с ним. Буферы приема, связанные с сокетом, будут освобождены вместе с файловым объектом.

В документации closesocket говорится, что отложенные операции отменяются, но асинхронные операции могут завершиться после возврата из функции. Похоже, закрытие сокета во время использования является поддерживаемым сценарием и не приведет к утечке памяти.

0 голосов
/ 10 сентября 2011

Не будет никакой утечки, и вы не обязаны читать поток в EOS перед закрытием.Если отправитель все еще отправляет после закрытия, он в конечном итоге получит «сброс соединения».

...