Ich weiß, wie Ports grundsätzlich funktionieren. Was ich jedoch nicht verstehe, ist, wie mehrere Clients gleichzeitig eine Verbindung zu Port 80 herstellen können. Ich weiß, dass jeder Client einen eigenen Port (für seinen Rechner) hat. Antwortet der Server von einem verfügbaren Port an den Client zurück und gibt einfach an, dass die Antwort von 80 kam? Wie funktioniert das?
Antworten
Zu viele Anzeigen?Zunächst einmal ist ein "Port" nur eine Nummer. Alles, was eine "Verbindung zu einem Port" wirklich darstellt, ist ein Paket, das diese Nummer in seinem "Zielport"-Headerfeld angegeben hat.
Nun gibt es zwei Antworten auf Ihre Frage, eine für zustandsabhängige und eine für zustandslose Protokolle.
Bei einem zustandslosen Protokoll (z. B. UDP) gibt es kein Problem, weil es keine "Verbindungen" gibt - mehrere Personen können Pakete an denselben Anschluss senden, und ihre Pakete kommen in beliebiger Reihenfolge an. Niemand befindet sich jemals im Zustand "verbunden".
Bei einem zustandsabhängigen Protokoll (wie TCP) wird eine Verbindung durch ein 4-Tupel identifiziert, das aus Quell- und Zielport sowie Quell- und Ziel-IP-Adresse besteht. Wenn also zwei verschiedene Rechner eine Verbindung zum selben Port auf einem dritten Rechner herstellen, gibt es zwei verschiedene Verbindungen, da sich die Quell-IPs unterscheiden. Wenn ein und derselbe Rechner (oder zwei hinter NAT oder mit derselben IP-Adresse) zweimal eine Verbindung zu einer Gegenstelle herstellt, werden die Verbindungen anhand des Quellports unterschieden (in der Regel ein zufälliger Port mit hoher Nummer).
Wenn ich mich von meinem Client aus zweimal mit demselben Webserver verbinde, haben die beiden Verbindungen aus meiner Sicht unterschiedliche Quellports und aus der Sicht des Webservers unterschiedliche Zielports. Es gibt also keine Zweideutigkeit, auch wenn beide Verbindungen dieselben Quell- und Ziel-IP-Adressen haben.
Häfen sind ein Weg, um Multiplex IP-Adressen, so dass verschiedene Anwendungen auf dasselbe IP-Adressen/Protokollpaar hören können. Solange eine Anwendung nicht ihr eigenes übergeordnetes Protokoll definiert, gibt es keine Möglichkeit, einen Port zu multiplexen. Wenn zwei Verbindungen, die das gleiche Protokoll verwenden, gleichzeitig identische Quell- und Ziel-IPs und identische Quell- und Ziel-Ports haben, muss es sich um dieselbe Verbindung handeln.
重要です。
Es tut mir leid, sagen zu müssen, dass die Antwort von "Borealid" ungenau und nicht ganz korrekt ist - erstens gibt es keinen Bezug zu Statefulness oder Statelessness, um diese Frage zu beantworten, und vor allem ist die Definition des Tupels für einen Socket falsch.
Denken Sie zunächst an die folgenden zwei Regeln:
-
Primärschlüssel eines Sockels: Ein Socket wird identifiziert durch
{SRC-IP, SRC-PORT, DEST-IP, DEST-PORT, PROTOCOL}
nicht von{SRC-IP, SRC-PORT, DEST-IP, DEST-PORT}
- Das Protokoll ist ein wichtiger Teil der Definition eines Sockets. -
OS Process & Socket Mapping: Ein Prozess kann mit mehreren Sockets verbunden sein (kann diese öffnen/abhören), was für viele Leser offensichtlich sein dürfte.
Beispiel 1: Zwei Clients, die sich mit demselben Server-Port verbinden, bedeuten: socket1 {SRC-A, 100, DEST-X,80, TCP}
y socket2{SRC-B, 100, DEST-X,80, TCP}
. Das bedeutet, dass Host A eine Verbindung zum Port 80 von Server X herstellt und ein anderer Host B ebenfalls eine Verbindung zum gleichen Port 80 von Server X herstellt. Wie der Server mit diesen beiden Sockeln umgeht, hängt davon ab, ob es sich um einen Single-Thread- oder einen Multiple-Thread-Server handelt (ich werde das später erklären). Wichtig ist, dass ein Server auf mehrere Sockets gleichzeitig hören kann.
Um die ursprüngliche Frage des Beitrags zu beantworten:
Unabhängig von zustandsbehafteten oder zustandslosen Protokollen können sich zwei Clients mit demselben Server-Port verbinden, da wir jedem Client einen anderen Socket zuweisen können (da sich die Client-IP definitiv unterscheiden wird). Ein und derselbe Client kann auch zwei Sockets haben, die sich mit demselben Serverport verbinden - da sich diese Sockets durch SRC-PORT
. Fairerweise muss man sagen, dass "Borealid" im Wesentlichen dieselbe richtige Antwort gegeben hat, aber der Verweis auf zustandslos/vollständig war irgendwie unnötig/verwirrend.
Um den zweiten Teil der Frage zu beantworten, wie ein Server weiß, welcher Socket zu antworten hat. Zunächst muss man verstehen, dass es für einen einzelnen Serverprozess, der denselben Port abhört, mehr als einen Socket geben kann (sei es vom selben Client oder von verschiedenen Clients). Solange ein Server weiß, welche Anfrage mit welchem Socket verbunden ist, kann er dem entsprechenden Client immer über denselben Socket antworten. Daher muss ein Server nie einen anderen Port in seinem eigenen Knoten öffnen als den ursprünglichen, über den der Client ursprünglich versucht hat, eine Verbindung herzustellen. Wenn ein Server andere Server-Ports zuweist, nachdem ein Socket gebunden wurde, dann verschwendet der Server meiner Meinung nach seine Ressourcen und muss den Client dazu bringen, sich erneut mit dem neu zugewiesenen Port zu verbinden.
Der Vollständigkeit halber noch ein wenig mehr:
Beispiel 2: Das ist eine sehr interessante Frage: "Können zwei verschiedene Prozesse auf einem Server denselben Port abhören". Wenn man das Protokoll nicht als einen der Socket definierenden Parameter betrachtet, lautet die Antwort nein. Das ist so, weil wir sagen können, dass in einem solchen Fall ein einzelner Client, der versucht, sich mit einem Server-Port zu verbinden, keinen Mechanismus hat, um zu erwähnen, mit welchem der beiden lauschenden Prozesse der Client sich verbinden will. Dies ist das gleiche Thema, das von Regel (2) behauptet wird. Dies ist jedoch eine FALSCHE Antwort, da das "Protokoll" auch ein Teil der Socket-Definition ist. Daher können zwei Prozesse im selben Knoten nur dann auf denselben Port hören, wenn sie unterschiedliche Protokolle verwenden. Zum Beispiel können zwei nicht miteinander verbundene Clients (z.B. einer benutzt TCP und ein anderer UDP) eine Verbindung zum selben Serverknoten und zum selben Port herstellen und kommunizieren, aber sie müssen von zwei verschiedenen Server-Prozessen bedient werden.
Servertypen - einzeln und mehrfach:
Wenn die Prozesse eines Servers auf einen Port hören, bedeutet dies, dass mehrere Sockets gleichzeitig eine Verbindung herstellen und mit demselben Server-Prozess kommunizieren können. Wenn ein Server nur einen einzigen Kindprozess verwendet, um alle Sockets zu bedienen, dann wird der Server als Single-Process/Threaded-Server bezeichnet, und wenn der Server viele Sub-Prozesse verwendet, um jeden Socket durch einen Sub-Prozess zu bedienen, dann wird der Server als Multi-Process/Thread-Server bezeichnet. Beachten Sie, dass ein Server unabhängig vom Servertyp immer denselben Ausgangssocket verwenden kann/sollte, um zurück zu antworten (es muss kein weiterer Server-Port zugewiesen werden).
Vorgeschlagene Bücher und den Rest der beiden Bände, wenn Sie können.
Eine Anmerkung zum Eltern-Kind-Prozess (als Antwort auf die Anfrage/Kommentar von 'Ioan Alexandru Cucu')
Wo immer ich ein Konzept in Bezug auf zwei Prozesse, z. B. A und B, erwähnt habe, ist zu beachten, dass sie nicht durch eine Eltern-Kind-Beziehung miteinander verbunden sind. Betriebssysteme (insbesondere UNIX) erlauben es einem Kindprozess, alle Dateideskriptoren (FD) von den Eltern zu erben. Somit können alle Sockets (in UNIX-ähnlichen Betriebssystemen sind sie auch Teil des FD), die ein Prozess A abhört, von vielen weiteren Prozessen A1, A2, abgehört werden, solange sie durch eine Eltern-Kind-Beziehung mit A verbunden sind. Aber ein unabhängiger Prozess B (d.h. ohne Eltern-Kind-Beziehung zu A) kann nicht auf denselben Socket hören. Außerdem ist zu beachten, dass diese Regel, die es zwei unabhängigen Prozessen verbietet, denselben Socket abzuhören, vom Betriebssystem (oder seinen Netzwerkbibliotheken) abhängt und bei weitem von den meisten Betriebssystemen befolgt wird. Man kann jedoch ein eigenes Betriebssystem erstellen, das diese Beschränkungen sehr wohl verletzen kann.
TCP / HTTP Abhören von Ports: Wie können viele Benutzer denselben Port nutzen?
Was passiert also, wenn ein Server auf einem TCP-Port auf eingehende Verbindungen wartet? Nehmen wir zum Beispiel an, Sie haben einen Webserver auf Port 80. Nehmen wir an, Ihr Computer hat die öffentliche IP-Adresse 24.14.181.229 und die Person, die versucht, sich mit Ihnen zu verbinden, hat die IP-Adresse 10.1.2.3. Diese Person kann eine Verbindung zu Ihnen herstellen, indem sie einen TCP-Socket zu 24.14.181.229:80 öffnet. Das ist ganz einfach.
Intuitiv (und fälschlicherweise) gehen die meisten Menschen davon aus, dass es in etwa so aussieht:
Local Computer | Remote Computer
--------------------------------
<local_ip>:80 | <foreign_ip>:80
^^ not actually what happens, but this is the conceptual model a lot of people have in mind.
Dies ist intuitiv, denn aus Sicht des Clients hat er eine IP-Adresse und verbindet sich mit einem Server unter IP:PORT. Da der Client eine Verbindung zu Port 80 herstellt, muss auch sein Port 80 sein? Das ist ein vernünftiger Gedanke, aber nicht das, was tatsächlich passiert. Wenn das richtig wäre, könnten wir nur einen Benutzer pro fremder IP-Adresse bedienen. Sobald ein entfernter Computer eine Verbindung herstellt, würde er die Verbindung von Port 80 zu Port 80 in Beschlag nehmen, und kein anderer könnte eine Verbindung herstellen.
Drei Dinge müssen verstanden werden:
1.) Auf einem Server ist ein Prozess Abhören auf einem Hafen. Sobald er eine Verbindung erhält, gibt er sie an einen anderen Thread weiter. Die Kommunikation nimmt den abhörenden Anschluss nicht in Anspruch.
2.) Verbindungen werden vom Betriebssystem durch das folgende 5er-Tupel eindeutig identifiziert: (local-IP, local-port, remote-IP, remote-port, protocol). Wenn ein Element in diesem Tupel anders ist, handelt es sich um eine völlig unabhängige Verbindung.
3.) Wenn ein Client eine Verbindung zu einem Server herstellt, wählt er eine zufälliger, unbenutzter Quellport höherer Ordnung . Auf diese Weise kann ein einzelner Client bis zu 64k Verbindungen zum Server für denselben Zielport haben.
Das ist also das, was wirklich erstellt wird, wenn ein Client eine Verbindung zu einem Server herstellt:
Local Computer | Remote Computer | Role
-----------------------------------------------------------
0.0.0.0:80 | <none> | LISTENING
127.0.0.1:80 | 10.1.2.3:<random_port> | ESTABLISHED
Ein Blick auf das, was tatsächlich passiert
Lassen Sie uns zunächst mit netstat sehen, was auf diesem Computer passiert. Wir verwenden Port 500 anstelle von 80 (weil eine ganze Reihe von Dingen auf Port 80 passiert, da es ein gängiger Port ist, aber funktionell macht es keinen Unterschied).
netstat -atnp | grep -i ":500 "
Wie erwartet, ist die Ausgabe leer. Starten wir nun einen Webserver:
sudo python3 -m http.server 500
Hier ist die Ausgabe, wenn Sie netstat erneut ausführen:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN -
Jetzt gibt es also einen Prozess, der aktiv an Port 500 lauscht (Status: LISTEN). Die lokale Adresse ist 0.0.0.0, was der Code für "listening for all" ist. Ein leicht zu begehender Fehler ist es, auf die Adresse 127.0.0.1 zu lauschen, die nur Verbindungen von dem aktuellen Computer akzeptiert. Dies ist also keine Verbindung, sondern bedeutet nur, dass ein Prozess bind() an Port IP angefordert hat, und dieser Prozess ist für die Bearbeitung aller Verbindungen zu diesem Port verantwortlich. Dies weist auf die Einschränkung hin, dass es nur einen Prozess pro Computer geben kann, der auf einem Port lauscht (es gibt Möglichkeiten, dies durch Multiplexing zu umgehen, aber das ist ein viel komplizierteres Thema). Wenn ein Webserver auf Port 80 lauscht, kann er diesen Port nicht mit anderen Webservern teilen.
Verbinden wir nun einen Benutzer mit unserem Rechner:
quicknet -m tcp -t localhost:500 -p Test payload.
Dies ist ein einfaches Skript ( https://github.com/grokit/dcore/tree/master/apps/quicknet ), das einen TCP-Socket öffnet, die Nutzlast sendet (in diesem Fall "Test payload."), einige Sekunden wartet und die Verbindung trennt. Die erneute Ausführung von netstat während dieses Vorgangs zeigt das Folgende an:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN -
tcp 0 0 192.168.1.10:500 192.168.1.13:54240 ESTABLISHED -
Wenn Sie eine Verbindung mit einem anderen Client herstellen und netstat erneut ausführen, sehen Sie Folgendes:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN -
tcp 0 0 192.168.1.10:500 192.168.1.13:26813 ESTABLISHED -
... das heißt, der Client verwendet einen anderen zufälligen Port für die Verbindung. Es kommt also nie zu Verwechslungen zwischen den IP-Adressen.
Normalerweise gabelt der Server für jede Client-Verbindung einen Kindprozess auf, der mit dem Client kommuniziert (TCP). Der übergeordnete Server übergibt dem untergeordneten Prozess einen eingerichteten Socket, der mit dem Client kommuniziert.
Wenn Sie die Daten von Ihrem Child-Server an einen Socket senden, erstellt der TCP-Stack des Betriebssystems ein Paket, das zum Client zurückgeht, und setzt den "from port" auf 80.
Mehrere Clients können sich mit demselben Port (z. B. 80) auf dem Server verbinden, da auf der Serverseite nach der Erstellung einer Steckdose y verbindlich (Einstellung von lokaler IP und Port) hören. wird auf dem Socket aufgerufen, der dem Betriebssystem mitteilt, dass es eingehende Verbindungen annehmen soll.
Wenn ein Client versucht, eine Verbindung zum Server an Port 80 herzustellen, wird die akzeptieren Aufruf auf dem Server-Socket aufgerufen wird. Dadurch wird ein neuer Socket für den Client erstellt, der versucht, eine Verbindung herzustellen, und in ähnlicher Weise werden neue Sockets für nachfolgende Clients erstellt, die denselben Port 80 verwenden.
Kursiv gedruckte Wörter sind Systemaufrufe.
Ref