gniazda używają różnych interfejsów API
To nie do końca prawda. Istnieje kilka dodatkowych funkcji do użycia z gniazdami, ale możesz używać np. Normalnego read()
i write()
na gnieździe fd.
w jaki sposób stosuje się tutaj „Wszystko jest plikiem”?
W tym sensie, że zaangażowany jest deskryptor pliku.
Jeśli twoja definicja „pliku” jest dyskretną sekwencją bajtów przechowywanych w systemie plików, to nie wszystko jest plikiem. Jeśli jednak twoja definicja pliku jest bardziej zrozumiała - przekaz informacji, tj. Połączenie we / wy - wtedy „wszystko jest plikiem” zaczyna mieć większy sens. Te rzeczy nieuchronnie wiążą się z sekwencjami bajtów, ale skąd pochodzą lub do których mogą się różnić mogą różnić się kontekstowo.
Jednak tak naprawdę nie jest to dosłownie zamierzone. Demon nie jest plikiem, demon jest procesem; ale jeśli robisz IPC, twoja metoda powiązania z innym procesem może zostać złagodzona przez jednostki stylu plików.
„Wszystko jest plikiem” to tylko przesada. To była powieść w 1970 roku i to było podstawową cechą wyróżniającą UNIX. Ale to tylko koncepcja marketingowa, a nie prawdziwa podstawa systemu UNIX, ponieważ oczywiście nie jest to prawda. Traktowanie WSZYSTKIEGO pliku jako pliku nie jest korzystne ani sensowne.
Czy procesor to plik? Czy twój program czyta () procesor, aby otrzymać nową instrukcję? Czy pamięć RAM jest plikiem? Czy twój program czyta () następny bajt?
W tamtym czasie istniały rodzaje systemów operacyjnych, które dały ci jeden interfejs API dla dyskietki i inny interfejs API dla dysku twardego, inny interfejs API dla taśmy magnetycznej i kilka różnych interfejsów API dla różnych terminali i tak dalej. Systemy mainframe IBM miały różne typy plików na dyskach twardych i dały ci inny interfejs API dla każdego z nich, wierzcie lub nie! Zatem podejście UNIX „jest to plik” wraz z podejściem „stdin / stdout / stderr”, przyniosło bardzo elegancką abstrakcję zarówno użytkownikom, jak i programistom.
W sieci ta szczególna abstrakcja po prostu się nie sprawdziła. I nie ma żadnej szkody, tylko nieco mniejsza ogólna elegancja i spójność systemu operacyjnego. Ale to działa. Czy widzisz
/dev/myinternetz/www/google/com/tcp/80
dzisiaj plik w dowolnym miejscu w systemie? Czy możesz otworzyć (), napisać () zapytanie i przeczytać () odpowiedź w ładnym HTML? Nie? Jest tak, ponieważ ta abstrakcja „jest plikiem” nie była bardzo przydatna do interakcji w sieci. W praktyce nie sprawdziłby się zbyt dobrze. Prawo nieszczelnych abstrakcji w akcji.źródło
/dev/tcp/www.google.com/80
. Nie jest to jednak rzeczywisty plik - bash po prostu go fałszuje./dev/mem
lub/dev/kmem
jeśli chcesz.Gniazda to pliki. Możesz używać
read
iwrite
na gnieździe: są one równoważne z połączeniemrecv
isend
przy pomocyflags=0
. Zamykacie jeclose
. Możesz przenosić je zdup
przyjaciółmi i znajomymi, jeśli chcesz przetasować deskryptory plików. Możesz ustawić niektóre flagi za pomocąfcntl
i używać buforowania stdio po wywołaniufdopen
. I tak dalej. Bardzo ważne jest, że możesz wywoływaćselect
ipoll
na dowolnym typie pliku, w tym na gniazdach, więc te funkcje pozwalają programowi blokować, dopóki nie otrzyma danych wejściowych w jakikolwiek sposób, po prostu przez wyświetlenie deskryptorów plików.Istnieją dodatkowe wywołania systemowe dla niektórych typów gniazd (
recv
isend
,shutdown
itp.), Podobnie jak dodatkowe wywołanie systemowe dla urządzeń (ioctl
).Nie wszystkie pliki mają nazwy , a te, które je mają, nie zawsze znajdują się w strukturze katalogów. Rury utworzone przez
pipe
(np. W potoku powłoki) i gniazda utworzone przezsocketpair
nie mają nazw, ale nadal są plikami. Gniazda utworzone przezsocket
mają nazwę, której składnia zależy od domeny. Ta nazwa jest przekazywanastruct sockaddr
dobind
funkcji i do innych funkcji. W przypadkuAF_UNIX
gniazda Unix ( ) nazwa to astruct sockaddr_un
, która jest rodziną i łańcuchem; w zależności od łańcucha może to być nazwa pliku (nazwane gniazda mogą być tworzonemknod
w wielu wariantach uniksowych) lub nie (abstrakcyjna przestrzeń nazw). W przypadkuAF_INET
gniazda IPv4 ( ) nazwa tostruct sockaddr_in
, zawierająca numer portu i adres IP oraz numerprotocol
zsocket
połączenia.źródło
Jeśli masz
stat
gniazdo, zobaczysz, że ma numer i-węzła i inne cechy zwykłych plików, więc sklasyfikowałbym go jako plik w systemie plików. Przykład:11/17. Dodatkowe informacje dla Linuksa (ext3): Gniazdo ma i-węzeł (który jest 256-bajtowym blokiem na dysku), ale nie ma żadnych bloków danych (możesz to zweryfikować przez wyodrębnienie i-węzła i sprawdzenie wskaźników bloków danych; lub przez uruchamianie „stat” debugfs, który pokazuje wartość Blockcount równą 0). Ma więc metadane pliku (właściciel, grupa, uprawnienia itp.), Ale nie zawiera danych na dysku. Jest to identyczne jak zwykły pusty plik (
touch /tmp/foo
), który również ma liczbę bloków równą 0. W pierwszym przypadku pole „typ” w i-węzle pokazuje „gniazdo”; w drugim przypadku pokazuje „zwykły plik”.Odniesienia: struktura i-węzła ext2 ;
stat
,dumpe2fs
idebugfs
polecenia.źródło
file
lub działaniastat
powoduje, że jest to plik.