2012-10-06 8 views
34

Ich wollte die genaue Funktion von bind() in TCP wissen. Was bedeutet es, eine lokale Adresse an den Socket "zu binden"? Wenn Sie dem Socket eine Portnummer zuweisen, warum verwenden wir sie dann nicht im Client? Ich weiß, dass der Anschluss vom Betriebssystem automatisch auf der Client-Seite zugewiesen wird, aber ich verstehe nicht, wie das alles funktioniert.Warum wird bind() in TCP verwendet? Warum wird es nur auf der Serverseite und nicht auf der Clientseite verwendet?

Nach bind(), hören wir(). Wie hängt die Bindung mit listen() zusammen? Wird das listen() wissen, dass bind() ausgeführt wurde? Wenn ja, welche Änderungen macht bind() so, dass es bekannt ist? Ich meine, wie hilft die Null für eine erfolgreiche Ausführung?

Ich bin durch viele Definitionen gegangen, aber nirgends, wo ich all das im Detail bekommen konnte. Wenn mir jemand das erklären kann, bin ich dankbar.

Antwort

14

Er weist die Portnummer des "lokalen" Endes zu.

Für einen Server-Socket ist dies der ultimative Weg - es ist genau das, was benötigt wird: Haben Sie Ihren Socket zum Beispiel an Port 80 für einen Webserver gebunden.

Für einen Client-Socket ist die lokale Adresse und der Port normalerweise nicht von Bedeutung. Sie tun also nicht bind(). Wenn der Server seine Clients auf eine bestimmte Portnummer oder eine Portnummer außerhalb eines bestimmten Bereichs beschränkt, können Sie auch bind() auf der Clientseite verwenden.

Auf der anderen Seite, Sie könnten auch listen() auf einem Sockel, wo Sie nicht bind() aufgerufen haben (eigentlich bin ich mir nicht sicher, aber es wäre sinnvoll). In diesem Szenario wäre der Serverport zufällig und der Serverprozess würde seinen Port über ein anderes Mittel dem Client mitteilen. Stellen Sie sich ein "Double-Connection" -Protokoll wie FTP vor, wo Sie eine Kontrollverbindung und eine Datenverbindung haben. Der Port, den die Datenverbindung überwacht, ist völlig willkürlich, muss aber auf der anderen Seite kommuniziert werden. Also wird der "automatisch bestimmte Port" verwendet und kommuniziert.

Ein Beispiel in Python:

import socket 
s = socket.socket() # create your socket 
s.listen(10) # call listen without bind 
s.getsockname() Which random port number did we get? 
# here results in ('0.0.0.0', 61372) 

s2 = socket.socket() # create client socket 
s2.connect(('localhost', 61372)) # connect to the one above 
s3, x = s.accept() # Python specific use; s3 is our connected socket on the server side 
s2.getpeername() 
# gives ('127.0.0.1', 61372) 
s2.getsockname() 
# gives ('127.0.0.1', 54663) 
s3.getsockname() 
# gives ('127.0.0.1', 61372), the same as s2.getpeername(), for symmetry 
s3.getpeername() 
#gives ('127.0.0.1', 54663), the same as s2.getsockname(), for symmetry 
#test the connection 
s2.send('hello') 
print s3.recv(10) 
+1

Diese Antwort ist unvollständig, da sie auch dafür verantwortlich ist, welche Netzwerkschnittstellen über eine IP-Adresse, z. '0.0.0.0' – user3338098

7

Er "bindet" einen Socket an eine Adresse, ansonsten weiß er nicht, auf welche Adresse (IP-Adresse/Port-Paar) er hören soll.

Und bind kann auch auf der Client-Seite verwendet werden. Ein Beispiel ist ein Computer mit mehreren Netzwerkkarten, die mit demselben Netzwerk verbunden sind, aber der Client möchte nur als von einer bestimmten Netzwerkadresse kommend angesehen werden.

Die Bindung wird nicht nur für TCP-Sockets verwendet, sondern auch für UDP-Sockets und andere Protokolle.

8

bind() definiert den lokalen Anschluss und Schnittstellenadresse für die Verbindung. connect() tut eine implizite bind("0.0.0.0", 0), wenn eine zuvor nicht getan wurde (wobei Null als "any" genommen wird).

Für ausgehende Verbindungen ist dies im Allgemeinen akzeptabel und bevorzugt. Das Betriebssystem wird einfach an "alle Schnittstellen" gebunden und wählt einen nicht nummerierten, ungenutzten Port. Sie müssen nur auf dem Client binden, wenn der Server erwartet, dass Sie von einem bestimmten Port oder Port-Bereich kommen. Einige Dienste erlauben nur Verbindungen von weniger als 1024 Portnummern, die nur vom Superuser gebunden werden können, obwohl das heutzutage nicht mehr bedeutet, dass jeder seinen eigenen Rechner steuert.

Für eingehende Verbindungen müssen Sie an einen bekannten Anschluss binden, damit die Clients wissen, wo Sie erreichbar sind.Sobald sie dies getan haben, haben sie dem Server ihre lokale Adresse/Port gegeben, so dass die Kommunikation dann in beide Richtungen fließen kann. listen() funktioniert nur nach einem bind() Anruf.

Alle Sockets müssen binden, ob sie UDP, TCP oder andere sind. Es wird nicht immer explizit gemacht.

+1

" 'listen()' funktioniert nur nach einem 'bind()' Aufruf. " Nein, wie Sie in [mein Beispiel] sehen können (http://stackoverflow.com/a/12763313/296974). – glglgl

+1

Wenn es funktioniert, dann ist 'bind()' implizit und wählt eine halb-zufällige Port-Nummer aus, die an alle Schnittstellen gebunden ist. Dies ist im Allgemeinen nicht sinnvoll (obwohl es seltene Ausnahmen gibt). –

+0

Das stimmt aber. – glglgl

0

Ich weiß, dass dies eine alte Frage, aber ich habe eine neue Antwort :)

Vielleicht möchten Sie zu einem Server verbinden, die nur eine begrenzte Anzahl von eingehenden Verbindungen pro IP erlaubt.

Wenn Sie mehrere Netzwerkschnittstellenkarten (und somit mehrere mögliche ausgehende ips zum Herstellen einer Verbindung) haben, können Sie bind() verwenden, indem Sie zyklisch durch alle ips blättern, um Ihre Verbindungen auszugleichen und somit mehrmals so viele Verbindungen wie sonst möglich wären.

Um eine Liste Ihrer Schnittstellen und ips zu erhalten, siehe this Antwort.

Verwandte Themen