Die Socket-API ist der De-facto-Standard für TCP / IP- und UDP / IP-Kommunikation (dh Netzwerkcode, wie wir ihn kennen). Eine seiner Kernfunktionen accept()
ist jedoch etwas magisch.
So leihen Sie sich eine semi-formale Definition aus:
accept () wird auf der Serverseite verwendet. Es akzeptiert einen empfangenen eingehenden Versuch, eine neue TCP-Verbindung vom Remote-Client 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 (an dem er accept
aufgerufen wurde) bleibt am selben Port geöffnet und wartet auf neue Verbindungen.
Wie funktioniert das accept
? Wie ist es implementiert? Es gibt viel Verwirrung zu diesem Thema. Viele Leute behaupten, dass Akzeptieren einen neuen Port öffnet und Sie über diesen mit dem Client kommunizieren. Dies ist jedoch offensichtlich nicht der Fall, da kein neuer Port geöffnet wird. Sie können tatsächlich über denselben Port mit verschiedenen Clients kommunizieren, aber wie? Wenn mehrere Threads recv
denselben Port aufrufen , woher wissen die Daten, wohin sie gehen sollen?
Ich denke, es ist etwas in der Art, wie die Adresse des Kunden mit einem Socket-Deskriptor verknüpft ist, und wann immer Daten eingehen, werden recv
sie an den richtigen Socket weitergeleitet, aber ich bin mir nicht sicher.
Es wäre großartig, eine gründliche Erklärung des Innenlebens dieses Mechanismus zu erhalten.
quelle
Antworten:
Ihre Verwirrung liegt in der Annahme, dass ein Socket durch Server IP: Server Port identifiziert wird. In Wirklichkeit werden Steckdosen durch ein Informationsquartett eindeutig identifiziert:
Client IP : Client Port
undServer 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 führt.
Beispiel zur Klärung:
Sagen wir an einen Server
192.168.1.1:80
und zwei Clients,10.0.0.1
und10.0.0.2
.10.0.0.1
Öffnet eine Verbindung am lokalen Port1234
und stellt eine Verbindung zum Server her. Jetzt hat der Server einen Socket, der wie folgt identifiziert wird:Jetzt
10.0.0.2
öffnet eine Verbindung zu lokal Port5678
und einer Verbindung zum Server. Jetzt verfügt der Server über zwei Sockets, die wie folgt gekennzeichnet sind:quelle
Nur um die Antwort des Benutzers "17 von 26" zu ergänzen.
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 'Protokoll' im IP-Datagramm identifiziert.
Somit ist es möglich, dass unterschiedliche Anwendungen auf dem Server mit genau denselben 4-Tupeln, jedoch unterschiedlich im Protokollfeld, mit demselben Client kommunizieren müssen. Beispielsweise
Apache auf der Serverseite spricht weiter (server1.com:880-client1:1234 auf TCP) und World of Warcraft spricht weiter (server1.com:880-client1:1234 auf UDP)
Sowohl der Client als auch der Server behandeln dies, da das Protokollfeld im IP-Paket in beiden Fällen unterschiedlich ist, selbst wenn alle anderen 4 Felder gleich sind.
quelle
Was mich verwirrte, als ich dies lernte, war, dass die Begriffe
socket
undport
suggerieren, dass sie etwas Physisches sind, obwohl es sich tatsächlich nur um Datenstrukturen handelt, die der Kernel verwendet, um die Details der Vernetzung zu abstrahieren.Als solche werden die Datenstrukturen implementiert, um Verbindungen von verschiedenen Clients trennen zu können. In Bezug auf , wie sie umgesetzt sind, dann ist die Antwort entweder a.) Spielt es keine Rolle, der Zweck der Sockets API genau ist , dass die Umsetzung nicht Materie oder b sollte.) Nur einen Blick. Schauen Sie sich neben den sehr empfohlenen Stevens-Büchern, die eine detaillierte Beschreibung einer Implementierung enthalten, die Quelle in Linux oder Solaris oder einem der BSDs an.
quelle
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 er verwendet) mit aktiven Sockets und überwacht den Server-Port. Wenn eine Nachricht empfangen wird (über den TCP / IP-Stack 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 übergeben. Andernfalls wird ein neuer Datenbankeintrag erstellt und ein neuer Handler für diesen Socket erstellt.
In den frühen Tagen des ARPAnet haben bestimmte Protokolle (FTP für einen) einen bestimmten Port auf Verbindungsanfragen abgehört und mit einem Handoff-Port geantwortet. Weitere Kommunikationen für diese Verbindung würden über den Handoff-Port erfolgen. Dies wurde durchgeführt, um die Leistung pro Paket zu verbessern: Computer waren damals um mehrere Größenordnungen langsamer.
quelle