Являются ли Unix файлы интернет-сокетов?

23

Я понимаю, что «Все - это файл» - это одна из основных концепций Unix, но в сокетах используются разные API, предоставляемые ядром (например, socket, sendto, recv и т. Д.), В отличие от обычных интерфейсов файловой системы.

Как это «Все это файл» применяется здесь?

user3718463
источник

Ответы:

26

сокеты используют разные API

Это не совсем так. Есть некоторые дополнительные функции для использования с сокетами, но вы можете использовать, например, обычный read()и write()на сокете fd.

Как это «Все это файл» применяется здесь?

В том смысле, что задействован файловый дескриптор.

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

Однако, это не совсем так. Демон не является файлом, демон является процессом; но если вы выполняете IPC, ваш метод связи с другим процессом может быть смягчен объектами стилей файлов.

лютик золотистый
источник
5
Я бы сказал, что точное выражение «все - это файл» должно быть «все интерфейсы - через файлы». Вы взаимодействуете с процессами через файлы (stdin / out / err, / proc / $ pid и т. Д.). Вы взаимодействуете с сетью через файлы (сокеты / файловые дескрипторы). Вы взаимодействуете с мышью через файл (/ dev / mouse).
Патрик
Однажды я клонировал дескриптор сокета, открыв его из / proc.
Иисус Навин
12

«Все это файл» - это просто преувеличение. Это было новшеством в 1970-х годах, и это было основной отличительной чертой UNIX. Но это всего лишь маркетинговая концепция, а не реальная основа UNIX, потому что это явно не соответствует действительности. Это не выгодно или разумно рассматривать ВСЕ как файл.

CPU - это файл? Ваша программа читает () процессор, чтобы получить новую инструкцию? RAM - это файл? Ваша программа читает () следующий байт?

В то время были виды ОС, которые давали вам один API для гибкого диска и другой API для жесткого диска, другой API для магнитной ленты и множество различных API для разных терминалов и так далее. Системы мэйнфреймов IBM имели разные типы файлов на жестких дисках и давали вам разные API для каждого из них, хотите верьте, хотите нет! Таким образом, подход «это файл» в UNIX вместе с подходом «stdin / stdout / stderr» принес очень элегантную абстракцию как пользователям, так и программистам.

С сетью эта конкретная абстракция просто не сработала. И в этом нет никакого вреда, только чуть меньше общей элегантности и согласованности ОС. Но это работает. Вы видите файл, называемый сегодня /dev/myinternetz/www/google/com/tcp/80где-нибудь в вашей системе? Можете ли вы открыть () его, написать () запрос и прочитать () ответ в хорошем HTML? Нет? Это потому, что эта абстракция "это файл" была не очень удобна для взаимодействия по сети. Это не сработает на практике. Закон вытекающих абстракций в действии.

kubanczyk
источник
9
Интересный факт: некоторые версии bash позволят вам открыться /dev/tcp/www.google.com/80. Это не настоящий файл, хотя bash просто притворяется.
user253751
2
@immibs: Более того, было бы разумно создать файловую систему, которая на самом деле это реализует.
Иисус Навин
Я полагаю, вы могли бы прочитать /dev/memили, /dev/kmemесли хотите.
Джейсон C
4
Обратите внимание, что в плане 9 это делается еще дальше, и, действительно, сетевые протоколы адресуются через псевдофайловую систему в соответствии с примером / dev / myinternetz / www / google / com / tcp / 80 (с другим путем, разумеется). Кроме того, физический ram на самом деле работает очень похоже на файл, вы mmap ram в свое виртуальное адресное пространство так же, как вы mmap файл в него. (Malloc реализован по этой идее).
Vality
1
План 9, в котором «все является файлом» до крайности, а также «все является прозрачным для сети», имеет некоторые весьма важные последствия. Например, нет необходимости в NAT, вы можете просто смонтировать стек TCP / IP вашего маршрутизатора (который является просто прозрачным для сети файлом (системой)) на вашем локальном компьютере и отправлять пакеты прямо с вашего маршрутизатора.
Jörg W Mittag
7

Сокеты файловые. Вы можете использовать readи writeна сокете: они эквивалентны вызову recvи sendс flags=0. Вы закрываете их close. Вы можете перемещать их вместе с dupдрузьями, если вам нужно перемешать файловые дескрипторы. Вы можете установить некоторые флаги fcntlи использовать буферизацию stdio после вызова fdopen. Список можно продолжить. Очень важно, что вы можете вызывать selectи pollдля любого типа файла, включая сокеты, поэтому эти функции позволяют программе блокировать, пока она не получит ввод любым способом, просто перечислив дескрипторы файлов.

Существуют дополнительные системные вызовы для некоторых типов сокетов ( recvи send, shutdownи т. Д.), Например, существует дополнительный системный вызов для устройств ( ioctl).

Не все файлы имеют имена , и из тех, которые имеют, они не всегда живут в структуре каталогов. Каналы, созданные pipe(например, в конвейере оболочки), и сокеты, созданные с помощью socketpair, не имеют имен, но они по-прежнему являются файлами. Сокеты, созданные с помощью, socketимеют имя, синтаксис которого зависит от домена. Это имя передается в struct sockaddrк bindи другим функциям. Для AF_UNIXсокета Unix ( ) имя - это a struct sockaddr_un, которое является семейством и строкой; в зависимости от строки это может быть имя файла (именованные сокеты могут создаваться mknodво многих вариантах Unix) или нет (абстрактное пространство имен). Для AF_INETсокета IPv4 ( ) это имя struct sockaddr_in, содержащее номер порта и IP-адрес, а также protocolот socketвызова.

Жиль "ТАК - перестань быть злым"
источник
7

Если вы statсокет, вы увидите, что он имеет номер инода и другие характеристики обычных файлов, поэтому я бы классифицировал его как файл в файловой системе. Пример:

# file live
live: socket
# stat live
File: `live'
  Size: 0               Blocks: 0          IO Block: 4096   socket
Device: fc03h/64515d    Inode: 198817      Links: 1
Access: (0660/srw-rw----)  Uid: (23129/  icinga)   Gid: (23130/icinga-cmd)
Access: 2014-11-07 09:27:59.000000000 -0800
Modify: 2014-11-05 09:27:03.000000000 -0800
Change: 2014-11-05 09:27:03.000000000 -0800

11/17. Дополнительная информация для Linux (ext3): Сокет имеет индекс (который является 256-байтовым блоком на диске), но не имеет никаких блоков данных (это можно проверить, извлекая индекс и изучая указатели блоков данных, или запуск debugfs 'stat', который показывает Blockcount 0). Таким образом, у него есть метаданные файла (владелец, группа, разрешения и т. Д.), Но нет содержимого данных на диске. Это идентично обычному пустому файлу ( touch /tmp/foo), который также имеет счетчик блоков 0. В первом случае поле «тип» в inode показывает «сокет»; во втором случае отображается «обычный файл».

Список литературы: структура in2 ext2 ; stat, dumpe2fsИ debugfsкоманды.

Майкл Мартинес
источник
1
Я бы сказал, что есть что-то для запуска fileили statдля создания файла.
Кевин