Sind Unix-Internet-Sockets-Dateien?

23

Ich verstehe, dass "Alles ist eine Datei" eines der Hauptkonzepte von Unix ist, aber Sockets verwenden andere vom Kernel bereitgestellte APIs (wie Socket, Sendto, Recv usw.), nicht wie normale Dateisystemschnittstellen.

Wie trifft das "Alles ist eine Datei" hier zu?

user3718463
quelle

Antworten:

26

Sockets verwenden unterschiedliche APIs

Das stimmt nicht ganz. Es gibt einige zusätzliche Funktionen für die Verwendung mit Sockets, aber Sie können z. B. normal read()und write()auf einem Socket fd verwenden.

Wie trifft das "Alles ist eine Datei" hier zu?

In dem Sinne, dass ein Dateideskriptor beteiligt ist.

Wenn Ihre Definition von "Datei" eine diskrete Folge von Bytes ist, die in einem Dateisystem gespeichert sind, ist nicht alles eine Datei. Wenn Ihre Dateidefinition jedoch handlicher ist - ein Conduit für Informationen, dh eine E / A-Verbindung -, ist "Alles ist eine Datei" sinnvoller. Diese Dinge beinhalten unweigerlich Sequenzen von Bytes, aber woher sie kommen oder wohin sie gehen, kann sich kontextuell unterscheiden.

Es ist jedoch nicht wirklich wörtlich gemeint. Ein Daemon ist keine Datei, ein Daemon ist ein Prozess. Wenn Sie jedoch IPC ausführen, wird Ihre Methode zum Verknüpfen mit einem anderen Prozess möglicherweise durch Entitäten im Dateiformat verringert.

Goldlöckchen
quelle
5
Ich würde sagen, eine genaue Umformulierung von "Alles ist eine Datei" sollte "Alle Schnittstellen sind durch Dateien" sein. Sie interagieren mit Prozessen über Dateien (stdin / out / err, / proc / $ pid usw.). Sie interagieren mit dem Netzwerk über Dateien (Sockets / Dateideskriptoren). Sie interagieren mit der Maus über eine Datei (/ dev / mouse).
Patrick
Ich habe einmal einen Socket-Handle geklont, indem ich ihn aus / proc heraus geöffnet habe.
Joshua
12

"Alles ist eine Datei" ist nur eine Übertreibung. Es war Roman in der 1970er Jahren und es war ein primäres Unterscheidungsmerkmal von UNIX. Aber es ist nur ein Marketingkonzept, keine wirkliche Grundlage von UNIX, weil es offensichtlich nicht wahr ist. Es ist nicht vorteilhaft oder sinnvoll, ALLES als Datei zu behandeln.

Ist die CPU eine Datei? Liest () Ihr Programm eine CPU, um eine neue Anweisung zu erhalten? Ist RAM eine Datei? Liest Ihr Programm das nächste Byte?

Damals gab es verschiedene Betriebssysteme, die Ihnen eine API für eine Diskette und eine andere API für eine Festplatte, eine andere API für Magnetbänder und eine Reihe verschiedener APIs für verschiedene Terminals usw. gaben. IBM Mainframe-Systeme hatten unterschiedliche Dateitypen auf Festplatten und gaben Ihnen für jeden eine andere API, ob Sie es glauben oder nicht! Der UNIX-Ansatz "Es ist eine Datei" brachte zusammen mit dem Ansatz "stdin / stdout / stderr" eine sehr elegante Abstraktion sowohl für Benutzer als auch für Programmierer.

Mit dem Netzwerk hat diese bestimmte Abstraktion einfach nicht funktioniert. Und es schadet nichts, nur etwas weniger Eleganz und Kohärenz des Betriebssystems. Aber es funktioniert. Sehen Sie eine Datei, die heute /dev/myinternetz/www/google/com/tcp/80irgendwo auf Ihrem System aufgerufen wird? Können Sie es öffnen (), eine Abfrage schreiben () und die Antwort in nettem HTML lesen ()? Nein? Dies liegt daran, dass diese Abstraktion "Ist eine Datei" für die Interaktion im Netzwerk nicht sehr praktisch war. In der Praxis würde es nicht allzu gut funktionieren. Gesetz der undichten Abstraktionen in Aktion.

kubanczyk
quelle
9
Unterhaltsame Tatsache: Bei einigen Versionen von bash können Sie öffnen /dev/tcp/www.google.com/80. Es ist jedoch keine tatsächliche Datei - Bash täuscht sie nur vor.
user253751
2
@immibs: Vielmehr wäre es vernünftigerweise möglich, ein Dateisystem zu erstellen, das dies tatsächlich implementiert.
Joshua
Ich nehme an, Sie könnten lesen /dev/memoder /dev/kmemwenn Sie wollten.
Jason C
4
Beachten Sie, dass Plan 9 dies weiterführt und Netzwerkprotokolle über ein Pseudo-Dateisystem angesprochen werden, wie es in Ihrem Beispiel / dev / myinternetz / www / google / com / tcp / 80 der Fall ist (natürlich mit einem anderen Pfad). Darüber hinaus funktioniert physischer RAM tatsächlich sehr ähnlich wie eine Datei. Sie ordnen RAM in Ihrem virtuellen Adressraum genau so zu, wie Sie eine Datei darin ordnen. (Malloc ist auf diese Idee umgesetzt).
Vality
1
Plan 9, bei dem "alles ist eine Datei" auf das Äußerste gebracht wird, und "alles ist netzwerktransparent", hat einige ziemlich starke Auswirkungen. Da NAT nicht erforderlich ist, können Sie den TCP / IP-Stack Ihres Routers (der nur eine netzwerktransparente Datei (System) ist) auf Ihrem lokalen Computer mounten und Pakete direkt von Ihrem Router senden.
Jörg W Mittag
7

Sockets sind Dateien. Sie können readund writean einem Socket verwenden: Sie entsprechen dem Aufrufen von recvund sendmit flags=0. Sie schließen sie mit close. Sie können sie mit dupund mit Freunden verschieben, wenn Sie Dateideskriptoren mischen müssen. Sie können einige Flags mit setzen fcntlund nach dem Aufruf stdio buffering verwenden fdopen. Die Liste geht weiter. Sehr wichtig ist , können Sie anrufen selectund pollauf jede Art von Datei, einschließlich Steckdosen, so dass diese Funktionen ein Programm ermöglichen zu blockieren , bis sie Eingang über irgendwelche Mittel erhält einfach durch Filedeskriptoren auflistet.

Es gibt zusätzliche Systemaufrufe für einige Socket - Typen ( recvund send, shutdownusw.), wie es ein zusätzlicher Systemaufruf für Geräte ist ( ioctl).

Nicht alle Dateien haben Namen , und von diesen leben sie nicht immer in der Verzeichnisstruktur. Pipes, die von pipe(z. B. in einer Shell-Pipeline) erstellt wurden, und Sockets, die von erstellt wurden, socketpairhaben keine Namen, aber sie sind immer noch Dateien. Sockets, die von erstellt wurden, sockethaben einen Namen, dessen Syntax von der Domäne abhängt. Der Name wird in einem übergeben struct sockaddrzu bindund anderen Funktionen. Bei einem Unix ( AF_UNIX) - Socket ist der Name a struct sockaddr_un, eine Familie und eine Zeichenfolge. Abhängig von der Zeichenfolge kann dies ein Dateiname sein (benannte Sockets können mit mknodvielen Unix-Varianten erstellt werden) oder nicht (der abstrakte Namespace). Bei einem IPv4 ( AF_INET) - Socket ist der Name ein struct sockaddr_in, der eine Portnummer und eine IP-Adresse sowie den Namen protocoldes socketAnrufs enthält.

Gilles 'SO - hör auf böse zu sein'
quelle
7

Wenn Sie statein Socket sind, werden Sie feststellen, dass es eine Inode-Nummer und andere Eigenschaften von regulären Dateien hat. Daher würde ich es als Datei im Dateisystem klassifizieren. Beispiel:

# 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

17.11. Zusätzliche Informationen für Linux (ext3): Ein Socket hat einen Inode (das ist ein 256-Byte-Block auf der Festplatte), aber keine Datenblöcke (Sie können dies überprüfen, indem Sie den Inode extrahieren und die Datenblockzeiger untersuchen oder indem Sie Ausführen von debugfs 'stat', das einen Blockcount von 0 anzeigt). Es verfügt also über Dateimetadaten (Eigentümer, Gruppe, Berechtigungen usw.), aber keinen Dateninhalt auf der Festplatte. Dies ist identisch mit einer normalen leeren Datei ( touch /tmp/foo), die ebenfalls eine Blockanzahl von 0 hat. Im ersten Fall zeigt das Feld "Typ" in der Inode "Socket" an. im zweiten Fall wird "normale Datei" angezeigt.

Referenzen: ext2 Inode-Struktur ; stat, dumpe2fsUnd debugfsBefehle.

Michael Martinez
quelle
1
Ich würde sagen, nur etwas zum Laufen zu haben fileoder statdarauf zu laufen, macht es zu einer Datei.
Kevin