Я розумію, що "Все є файлом" є однією з основних концепцій Unix, але сокети використовують різні API, які надаються ядром (наприклад, socket, sendto, recv тощо), не як звичайні інтерфейси файлової системи.
Як тут застосовується це "Все є файлом"?
Я розумію, що "Все є файлом" є однією з основних концепцій Unix, але сокети використовують різні API, які надаються ядром (наприклад, socket, sendto, recv тощо), не як звичайні інтерфейси файлової системи.
Як тут застосовується це "Все є файлом"?
Відповіді:
розетки використовують різні API
Це не зовсім вірно. Існує кілька додаткових функцій для використання з розетками, але ви можете користуватися, наприклад, нормальним read()
і write()
на sod fd.
як це ставиться тут "Все є файлом"?
У тому сенсі, що задіяний дескриптор файлу.
Якщо ваше визначення "файл" - це дискретна послідовність байтів, що зберігаються у файловій системі, то не все є файлом. Однак якщо ваше визначення файлу більше схоже на - канал для інформації, тобто з'єднання вводу / виводу - тоді "все є файлом" починає мати більше сенсу. Ці речі неминуче включають послідовності байтів, але там, де вони походять або переходять, можуть різнитися в контексті.
Однак насправді це не задумано буквально. Демон не є файлом, демон є процесом; але якщо ви робите IPC, ваш метод зв’язку з іншим процесом цілком може бути пом’якшений суб'єктами стилю файлів.
"Все - файл" - це лише завищення. Це було новим у 1970-х, і було головною відмітною характеристикою UNIX. Але це просто маркетингова концепція, а не реальна основа UNIX, адже це, очевидно, неправда. Не вигідно чи розумно ставитися до ВСІХ як до файлу.
Чи є процесор файлом? Чи читає ваша програма () процесор, щоб отримати нову інструкцію? Чи є RAM файлом? Чи читає ваша програма () наступний байт?
Тоді існували види ОС, які давали вам один API для дискети та інший API для жорсткого диска, інший API для магнітної стрічки та купу різних API для різних терміналів тощо. Системи IBM mainframe мали різні типи файлів на жорстких дисках і надавали вам різні API для кожного з них, вірите чи ні! Тож підхід UNIX "це файл" разом із підходом "stdin / stdout / stderr" приніс дуже елегантну абстракцію як користувачам, так і програмістам.
У мережі ця конкретна абстракція просто не вийшла. І шкоди немає, лише дещо менша загальна елегантність та узгодженість ОС. Але це працює. Чи бачите ви файл, який називається /dev/myinternetz/www/google/com/tcp/80
десь у вашій системі сьогодні? Чи можете ви відкрити (), написати () запит і прочитати () відповідь у приємному HTML? Ні? Це тому, що ця абстракція "є файлом" була не дуже зручною для взаємодії в мережі. На практиці це не буде надто добре. Закон протікаючих абстракцій у дії.
/dev/tcp/www.google.com/80
. Це не фактичний файл - bash просто підробляє його.
/dev/mem
чи /dev/kmem
хочете.
Розетки - це файли. Ви можете використовувати 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 ( ) назва - це а struct sockaddr_un
, що є сім'єю та рядком; Залежно від рядка, це може бути ім'я файлу (названі сокети можуть бути створені у mknod
багатьох варіантах unix) чи ні (абстрактна область імен). Для AF_INET
сокета IPv4 ( ) ім'я є а struct sockaddr_in
, що містить номер порту та IP-адресу плюс плюс protocol
від socket
дзвінка.
Якщо ви stat
сокет, ви побачите, що він має номер inode та інші характеристики звичайних файлів, тому я би класифікував його як файл у файловій системі. Приклад:
# 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): у сокета є inode (який є 256-байтовим блоком на диску), але немає блоків даних (ви можете перевірити це, витягнувши inode та вивчивши покажчики блоку даних; або працює налагодження 'stat', який показує кількість записів у 0). Отже, у нього є метадані файлів (власник, група, дозволи тощо), але на диску немає вмісту даних. Це ідентично звичайному порожньому файлу ( touch /tmp/foo
), який також має кількість блоків 0. У першому випадку поле "type" у вкладі показує "socket"; у другому випадку він показує "звичайний файл".
Посилання: структура inode ext2 ; stat
, dumpe2fs
і debugfs
команди.
file
або stat
ввімкне, робить це файлом.