Windows заботится о закрытии сокетов при выходе из процессов?
12
Я прочитал этот вопрос о Linux. Может ли порт быть привязан после завершения процесса?
Похоже, что Linux очищается после выхода из процессов и оставления открытых сокетов. Мне было интересно, есть ли какие-либо спецификации о том, как это работает в Windows. Постоянно ли ОС заботится о закрытии сокетов для процессов, которые выходят без их закрытия?
Хотя открытые дескрипторы объектов ядра автоматически закрываются при завершении процесса, сами объекты существуют до тех пор, пока все открытые дескрипторы к ним не будут закрыты. Следовательно, объект останется действительным после того, как процесс, использующий его, завершит свою работу, если другой процесс имеет открытый дескриптор.
Все дескрипторы объекта, открытые процессом, закрыты.
[...]
Linux
exit(3) - Руководство программиста Linux (функции libc)
Все открытые потоки stdio (3) сбрасываются и закрываются.
_exit(2) - Руководство программиста Linux (системные вызовы ядра)
Функция _exit()завершает вызывающий процесс «немедленно». Все дескрипторы открытого файла, принадлежащие процессу, закрыты; любые дочерние элементы процесса наследуются процессом 1, init , а родительскому процессу отправляется сигнал SIGCHLD.
Обратите внимание, что в обеих операционных системах
Сокеты - это только один тип файловых дескрипторов (fd's) / объектов ядра, поэтому вышеизложенное относится в равной степени к файлам и сокетам.
Описания файлов на Unix, а также дескрипторы объектов объекты ядра на Windows, могут принадлежать нескольким процессам - они их ручки могут быть унаследованы дочерними процессами и даже ходили с помощью специальных функций IPC.
Файл или сокет закрываются только тогда, когда все fd, указывающие на него, уничтожены.
Сокеты TCP являются особым случаем из-за их состояний TIME_WAIT. Например, если вы завершаете работу приложения, прослушивающего порт TCP, вы часто не можете сразу привязаться к одному и тому же порту.
Haimg
2
Нет. Файловые дескрипторы и дескрипторы объектов принадлежат и доступны только одному процессу и являются строго объектами процесса . Это описание файла и базовый объект, которые являются общими для процессов.
JdeBP
5
В Windows сокет является связующим звеном между конечной точкой связи и процессом. Вот почему, когда вы дублируете сокет, вы получаете два сокета, но только одну конечную точку. Вот почему вы не можете передать сокет из одного процесса в другой, не создав новый сокет в другом процессе.
Если процесс перестает существовать, его сокеты обязательно прекращают существовать. Не существует концепции сокета без процесса его удержания. Вот почему даже драйверы ядра Windows, которые хотят создавать сокеты на уровне ядра, должны указывать процесс для владения сокетом или вызывать функцию из контекста процесса, который может владеть сокетом. (Или они могут управлять конечными точками напрямую, без использования сокетов.)
Ваш вопрос, похоже, на самом деле касается не сокетов, а самих конечных точек связи. Сокет имеет ссылку на свою конечную точку связи. Когда сокет исчезает, счетчик ссылок падает. Если он достигнет нуля, он будет удален, как только это допустимо, учитывая требования протокола связи, с которым связана конечная точка. TCP имеет состояние TIME_WAIT, во время которого конечная точка должна поддерживаться для обработки любых «оставшихся» пакетов.
Нет, это не так. Так как Windows NT версии 3. 5 , возможно. Но DOS-Windows сильно отличалась от Windows NT, когда дело дошло до сокетов; кроме того, DOS-Windows 95 значительно отличалась от DOS-Windows 3.1. Приложения Win16 требовались для вызова, WSACleanup()иначе произошла утечка; и была неприятная проблема в DOS-Windows 9x, задокументированная в статье MSKB № 156319, с родительскими процессами, делающими недействительными сокеты, передаваемые их дочерним элементам, вызванным довольно различной семантикой выхода процессов DOS-Windows для сокетов.
JdeBP
1
@JdeBP: А как насчет Windows NT 3. 1 - она выполняла автоматическую очистку?
В Windows сокет является связующим звеном между конечной точкой связи и процессом. Вот почему, когда вы дублируете сокет, вы получаете два сокета, но только одну конечную точку. Вот почему вы не можете передать сокет из одного процесса в другой, не создав новый сокет в другом процессе.
Если процесс перестает существовать, его сокеты обязательно прекращают существовать. Не существует концепции сокета без процесса его удержания. Вот почему даже драйверы ядра Windows, которые хотят создавать сокеты на уровне ядра, должны указывать процесс для владения сокетом или вызывать функцию из контекста процесса, который может владеть сокетом. (Или они могут управлять конечными точками напрямую, без использования сокетов.)
Ваш вопрос, похоже, на самом деле касается не сокетов, а самих конечных точек связи. Сокет имеет ссылку на свою конечную точку связи. Когда сокет исчезает, счетчик ссылок падает. Если он достигнет нуля, он будет удален, как только это допустимо, учитывая требования протокола связи, с которым связана конечная точка. TCP имеет состояние TIME_WAIT, во время которого конечная точка должна поддерживаться для обработки любых «оставшихся» пакетов.
источник
Да. Это был способ Windows
3.19598XP (по крайней мере, я знаю наверняка с XP).источник
WSACleanup()
иначе произошла утечка; и была неприятная проблема в DOS-Windows 9x, задокументированная в статье MSKB № 156319, с родительскими процессами, делающими недействительными сокеты, передаваемые их дочерним элементам, вызванным довольно различной семантикой выхода процессов DOS-Windows для сокетов.