Как точно работают функции fopen(), fclose()?

Мне просто интересно узнать о функциях fopen, fclose, socket и closesocket. Когда вы вызываете fopen или открываете сокет, что именно происходит (особенно память разумная)?

Может ли открытие файлов/сокетов без их закрытия вызвать утечку памяти?

И в-третьих, как создаются сокеты и как они выглядят как память?

Меня также интересует роль операционной системы (Windows) при чтении сокетов и отправке данных.

Ответ 1

Отказ от ответственности: в основном я не имею права говорить об этом. Было бы здорово, если бы кто-нибудь более осведомленный тоже отправил.

Файлы

Детали того, как реализованы такие вещи, как fopen(), будут сильно зависеть от операционной системы (например, UNIX имеет fopen()). Даже версии Windows могут сильно отличаться друг от друга.

Я дам вам свое представление о том, как это работает, но в основном это предположение.

  • При вызове fopen выделяет объект FILE в куче. Обратите внимание, что данные в объекте FILE недокументированы - FILE - это непрозрачная структура, вы можете использовать указатели только для FILE из вашего кода.
  • Объект FILE инициализируется. Например, что-то вроде fillLevel = 0, где fillLevel - это количество буферизованных данных, которые еще не были очищены.
  • Вызов драйвера файловой системы (драйвер FS) открывает файл и предоставляет ему дескриптор, который помещается где-то в структуру FILE.
    • Для этого драйвер FS определяет адрес жесткого диска, соответствующий запрошенному пути, и внутренне запоминает этот адрес жесткого диска, поэтому он может позже выполнять вызовы на предмет простуды и т.д.
      • Драйвер FS использует своего рода таблицу индексирования (хранящуюся на жестком диске) для определения адреса жесткого диска, соответствующего запрошенному пути. Это будет сильно отличаться в зависимости от типа файловой системы - FAT32, NTFS и т.д.
      • Драйвер FS использует драйвер жесткого диска для выполнения реальных операций чтения и записи на жесткий диск.
  • Кэш может быть выделен в ОЗУ для файла. Таким образом, если пользователь запрашивает 1 байт для чтения, С++ может читать KB на всякий случай, поэтому последующие чтения будут мгновенными.
  • Указатель на выделенный FILE возвращается из fopen.

Если вы откроете файл и никогда его не закрываете, некоторые вещи будут течь, да. Структура FILE будет протекать, внутренние данные драйвера FS будут протекать, и кеш (если есть) тоже будет протекать.

Но память - это не единственная вещь, которая будет протекать. Сам файл будет протекать, потому что ОС будет думать, что он откроется, когда он не будет. Это может стать проблемой, например, в Windows, где файл, открытый в режиме записи, не может быть снова открыт в режиме записи до его закрытия.

Если ваше приложение выходит без закрытия какого-либо файла, большинство ОС будут очищаться после него. Но это не так много, потому что ваше приложение, вероятно, будет работать в течение долгого времени до выхода, и в течение этого времени ему все равно нужно будет правильно закрыть все файлы. Кроме того, вы не можете полностью полагаться на ОС для очистки после вас - это не гарантируется в стандарте C.

Розетки

Реализация сокета будет зависеть от типа сокета - сетевого прослушивателя, сетевого клиентского сокета, межпроцессного сокета и т.д.

Полное обсуждение всех типов сокетов и их возможных реализаций не поместилось бы здесь.

Короче:

  • Подобно файлу, сокет хранит некоторую информацию в ОЗУ, описывая вещи, относящиеся к его работе, такие как IP удаленного узла.
  • он может также иметь кэши в ОЗУ по соображениям производительности
  • он может удерживать конечные ресурсы ОС, такие как открытые порты, что делает их недоступными для использования другими приложениями

Все эти вещи будут протекать, если вы не закрываете сокет.

Роль ОС в сокетах

ОС реализует стандарт TCP/IP, Ethernet и другие протоколы, необходимые для планирования/отправки/приема соединений и обеспечения их доступности для пользовательского кода через API, например, Berkeley Sockets.

ОС будет делегировать сетевой ввод-вывод (связь с сетевой картой) сетевому драйверу.