it-swarm.com.de

Wie funktioniert die Socket-API accept ()?

Die Socket-API ist der De-facto-Standard für die TCP/IP- und UDP/IP-Kommunikation (dh den bekannten Netzwerkcode). Eine seiner Kernfunktionen, accept(), ist jedoch etwas magisch.

So leihen Sie eine semi-formale Definition aus:

accept () wird serverseitig verwendet. Es akzeptiert einen empfangenen eingehenden Versuch, eine neue TCP vom Remote-Client aus zu erstellen, und erstellt einen neuen Socket, der dem Socket-Adresspaar dieser Verbindung zugeordnet ist.

Mit anderen Worten, accept gibt einen neuen Socket zurück, über den der Server mit dem neu verbundenen Client kommunizieren kann. Der alte Socket (auf dem accept aufgerufen wurde) bleibt auf demselben Port geöffnet und wartet auf neue Verbindungen.

Wie funktioniert accept? Wie ist es implementiert? Es gibt viel Verwirrung in diesem Thema. Viele Leute behaupten, dass Accept einen neuen Port öffnet und Sie über diesen mit dem Client kommunizieren. Dies ist jedoch offensichtlich nicht der Fall, da kein neuer Hafen eröffnet wird. Sie können tatsächlich über denselben Port mit verschiedenen Clients kommunizieren, aber wie? Woher wissen die Daten, wenn mehrere Threads recv auf demselben Port aufrufen?

Ich vermute, es ist etwas in der Art, wie die Adresse des Kunden mit einem Socket-Deskriptor verknüpft ist, und wann immer Daten durch recv kommen, werden sie an den richtigen Socket weitergeleitet, aber ich bin nicht sicher.

Es wäre großartig, eine gründliche Erklärung der Funktionsweise dieses Mechanismus zu erhalten.

116
Eli Bendersky

Ihre Verwirrung liegt in der Annahme, dass ein Socket durch die Server-IP identifiziert wird: Server-Port. In Wirklichkeit werden Sockets durch ein Quartett von Informationen eindeutig identifiziert:

Client IP : Client Port und Server IP : Server Port

Während die Server-IP und der Server-Port in allen akzeptierten Verbindungen konstant sind, können Sie anhand der clientseitigen Informationen verfolgen, wohin alles geht.

Beispiel zur Verdeutlichung:

Angenommen, wir haben einen Server bei 192.168.1.1:80 und zwei Kunden, 10.0.0.1 und 10.0.0.2.

10.0.0.1 öffnet eine Verbindung am lokalen Port 1234 und stellt eine Verbindung zum Server her. Auf dem Server wurde nun ein Socket wie folgt identifiziert:

10.0.0.1:1234 - 192.168.1.1:80  

Jetzt 10.0.0.2 öffnet eine Verbindung am lokalen Port 5678 und stellt eine Verbindung zum Server her. Der Server verfügt nun über zwei Sockets, die wie folgt gekennzeichnet sind:

10.0.0.1:1234 - 192.168.1.1:80  
10.0.0.2:5678 - 192.168.1.1:80
129
17 of 26

Nur um die Antwort von Benutzer "17 von 26" hinzuzufügen

Der Socket besteht tatsächlich aus 5 Tupeln (Quell-IP, Quell-Port, Ziel-IP, Ziel-Port, Protokoll). Hier könnte das Protokoll TCP oder UDP oder ein beliebiges Transportschichtprotokoll sein. Dieses Protokoll wird im Paket aus dem Feld 'protocol' im IP-Datagramm identifiziert.

Auf diese Weise ist es möglich, dass verschiedene Anwendungen auf dem Server auf genau den gleichen 4-Tupeln mit demselben Client kommunizieren, die sich jedoch im Protokollfeld unterscheiden. Beispielsweise

Apache auf der Serverseite spricht über (server1.com:880-client1:1234 unter TCP) und World of Warcraft spricht über (server1.com:880-client1:1234 unter UDP)

Sowohl der Client als auch der Server behandeln dies als Protokollfeld im IP-Paket. In beiden Fällen ist dies unterschiedlich, auch wenn alle anderen 4 Felder gleich sind.

67
Methos

Was mich verwirrte, als ich das lernte, war, dass die Begriffe socket und port darauf hindeuten, dass es sich um etwas Physisches handelt, obwohl es sich nur um Datenstrukturen handelt, mit denen der Kernel die Details abstrahiert Vernetzung.

Daher werden die Datenstrukturen implementiert, um Verbindungen von verschiedenen Clients fernzuhalten. Was wie betrifft, lautet die Antwort entweder a.) Es spielt keine Rolle, der Zweck der Sockets-API ist genau, dass die Implementierung keine Rolle spielen sollte, oder b.) Nur a aussehen. Neben den sehr empfohlenen Stevens-Büchern, die eine detaillierte Beschreibung einer Implementierung enthalten, sollten Sie die Quelle in Linux oder Solaris oder einer der BSDs prüfen.

11
a2800276

Wie der andere sagte, wird ein Socket durch ein 4-Tupel (Client-IP, Client-Port, Server-IP, Server-Port) eindeutig identifiziert.

Der Serverprozess, der auf der Server-IP ausgeführt wird, verwaltet eine Datenbank (dh es ist mir egal, welche Art von Tabelle/Liste/Baum/Array/magische Datenstruktur verwendet wird) von aktiven Sockets und Listenern auf dem Server-Port. Wenn eine Nachricht empfangen wird (über den TCP/IP-Stapel des Servers), werden die Client-IP und der -Port mit der Datenbank verglichen. Wenn die Client-IP und der Client-Port in einem Datenbankeintrag gefunden werden, wird die Nachricht an einen vorhandenen Handler weitergeleitet. Andernfalls wird ein neuer Datenbankeintrag erstellt und ein neuer Handler für diesen Socket erstellt.

In den frühen Tagen des ARPAnet empfingen bestimmte Protokolle (ein FTP-Protokoll) einen bestimmten Port für Verbindungsanfragen und antworteten mit einem Handoff-Port. Weitere Kommunikationen für diese Verbindung würden über den Übergabeport gehen. Dies wurde durchgeführt, um die Leistung pro Paket zu verbessern: Computer waren in jenen Tagen um mehrere Größenordnungen langsamer.

1
John R Strohm