Lassen Sie uns die Gerätedateien schnell überprüfen: Unter Linux kommunizieren Anwendungsprogramme rad- und Schreibvorgänge über Dateideskriptoren an den Kernel . Das funktioniert hervorragend für Dateien, und es stellte sich heraus, dass dieselbe API für Zeichengeräte verwendet werden kann , die Zeichenströme erzeugen und verbrauchen, und Geräte blockiert , die Blöcke fester Größe an einer Direktzugriffsadresse lesen und schreiben, indem sie nur so tun, als ob diese sind auch Dateien.
Es war jedoch eine Möglichkeit erforderlich, diese Geräte zu konfigurieren (Baudraten einstellen usw.), und dafür wurde der ioctl- Aufruf erfunden. Es wird lediglich eine gerätespezifische Datenstruktur und die Art der E / A-Steuerung übergeben, die für den Kernel verwendet wird, und die Ergebnisse werden in derselben Datenstruktur zurückgegeben. Es handelt sich also um eine sehr generische erweiterbare API, die für viele Zwecke verwendet werden kann .
Wie passen nun Netzwerkoperationen zusammen? Eine typische Netzwerkserveranwendung möchte eine Bindung an eine Netzwerkadresse herstellen, einen bestimmten Port abhören (z. B. 80 für HTTP oder 22 für ssh). Wenn ein Client eine Verbindung herstellt , möchte er Daten an diesen Client senden und von diesem empfangen . Und die doppelten Operationen für den Kunden.
Es ist nicht offensichtlich, wie dies in Dateivorgänge eingepasst werden soll (obwohl dies möglich ist, siehe Plan 9 ). Deshalb haben die UNIX-Designer eine neue API erfunden: Sockets . Einzelheiten entnehmen Sie bitte den für Abschnitt 2 Manpages finden socket
, bind
, listen
, connect
, send
und recv
. Beachten Sie, dass der socket
Aufruf , obwohl er sich von der Datei-E / A-API unterscheidet, auch einen Dateideskriptor zurückgibt. Es gibt zahlreiche Tutorials zur Verwendung von Sockets im Web, google ein bisschen.
Bisher war dies alles reines UNIX. Zum Zeitpunkt der Erfindung der Sockets sprach niemand über Netzwerkschnittstellen. Und da diese API sehr alt ist, ist sie für eine Vielzahl von Netzwerkprotokollen definiert, die über das Internetprotokoll hinausgehen (siehe AF_*
Konstanten), obwohl nur einige davon unter Linux unterstützt werden.
Da Computer jedoch mehrere Netzwerkkarten erhielten, war hierfür eine gewisse Abstraktion erforderlich. Unter Linux ist dies die Netzwerkschnittstelle (NI). Es wird nicht nur für eine Hardware verwendet, sondern auch für verschiedene Tunnel, Benutzeranwendungsendpunkte, die als Tunnel wie OpenVPN usw. dienen. Wie bereits erläutert, basiert die Socket-API nicht auf (speziellen) Dateien und ist vom Dateisystem unabhängig. Auf die gleiche Weise werden auch Netzwerkschnittstellen nicht im Dateisystem angezeigt. Die NIs werden jedoch im Dateisystem /proc
und /sys
(sowie in anderen Netzwerk-Tunables) verfügbar gemacht.
Ein NI ist einfach eine Kernel-Abstraktion eines Endpunkts, an dem Netzwerkpakete in den Kernel eintreten und diesen verlassen. Sockets hingegen werden verwendet, um Pakete mit Anwendungen zu kommunizieren. An der Verarbeitung eines Pakets muss kein Socket beteiligt sein. Wenn beispielsweise die Weiterleitung aktiviert ist, kann ein Paket auf einem NI eingehen und auf einem anderen abreisen. In diesem Sinne sind Sockets und Netzwerkschnittstellen völlig unabhängig.
Aber es musste eine Möglichkeit geben, NIs zu konfigurieren, genau wie Sie eine Möglichkeit brauchten, Block- und Zeichengeräte zu konfigurieren. Und da Sockets bereits einen Dateideskriptor zurückgegeben haben, war es etwas logisch, nur einen ioctl
Dateideskriptor zuzulassen . Das ist die NetDevice- Schnittstelle, die Sie verlinkt haben.
Es gibt eine ganze Reihe anderer Missbräuche von Systemaufrufen auf ähnliche Weise, beispielsweise zum Paketfiltern, zur Paketerfassung usw.
All dies ist Stück für Stück gewachsen und an vielen Stellen nicht besonders logisch. Wenn es auf einmal entworfen worden wäre, hätte man wahrscheinlich eine orthogonalere API erstellen können.