web-dev-qa-db-fra.com

Pourquoi bind () est-il utilisé dans TCP? Pourquoi est-il utilisé uniquement côté serveur et non côté client?

Je voulais connaître la fonction exacte de bind () dans TCP. Qu'est-ce que cela signifie en "liant" une adresse locale à la prise? S'il s'agit d'affecter un numéro de port au socket, pourquoi ne l'utilisons-nous pas dans le client? Je sais que le port est attribué automatiquement par le système d'exploitation du côté client, mais je ne vois pas comment cela fonctionne.

Après bind (), nous écoutons (). Quel est le lien entre bind et listen ()? Listen () saura-t-il que bind () a été exécuté? Si tel est le cas, quels changements bind () fait-il pour qu'il soit connu? Je veux dire, comment retourner zéro pour une exécution réussie aide-t-il?

J'ai passé en revue de nombreuses définitions, mais je ne peux pas obtenir tout cela en détail. Donc, si quelqu'un peut s'il vous plaît expliquer cela, je vous en serai reconnaissant.

42
Crocode

Il attribue le numéro de port de l'extrémité "locale".

Pour un socket de serveur, c’est la solution ultime - c’est exactement ce dont vous avez besoin: associez votre socket au port 80 pour un serveur Web, par exemple.

Pour un socket client, cependant, l'adresse locale et le port n'ont généralement pas d'importance. Donc, vous n'avez pas bind(). Si le serveur limite ses clients à un certain numéro de port, ou à un numéro de port situé en dehors d'une plage donnée, vous pouvez également utiliser bind() du côté client.

D'autre part, vous pourriez aussi bien être capable de listen() sur un socket où vous n'avez pas appelé bind() (en fait, je n'en suis pas sûr, mais cela aurait du sens). Dans ce scénario, le port de votre serveur serait aléatoire et le processus serveur communiquerait son port par un moyen différent au client. Imaginez un protocole de "double connexion" tel que FTP, où vous avez une connexion de contrôle et une connexion de données. Le port sur lequel la connexion de données est à l’écoute est complètement arbitraire, mais doit être communiqué à l’autre côté. Ainsi, le "port déterminé automatiquement" est utilisé et communiqué.

Un exemple en 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)
18
glglgl

bind() définit le port local et l'adresse d'interface pour la connexion. connect() effectue une bind("0.0.0.0", 0) implicite si aucune n'a déjà été effectuée (zéro étant considéré comme "quelconque").

Pour les connexions sortantes, cela est généralement acceptable et préféré. Le système d’exploitation se liera simplement à «toutes les interfaces» et choisira un port inutilisé comportant un numéro élevé. Vous devez uniquement établir une liaison sur le client si le serveur s'attend à ce que vous veniez d'un port ou d'une plage de ports spécifique. Certains services n'autorisent que les connexions provenant de numéros de port inférieurs à 1024, ceux-ci ne pouvant être lus que par le superutilisateur, bien que cela ne veuille plus dire grand-chose de nos jours maintenant que tout le monde contrôle sa propre machine.

Pour les connexions entrantes, vous devez vous connecter à un port connu afin que les clients sachent où vous contacter. Une fois qu'ils le font, ils ont fourni au serveur leur adresse/port local afin que la communication puisse ensuite circuler dans les deux sens. listen() ne fonctionnera qu’après un appel bind().

Tous les sockets doivent être liés, qu’ils soient UDP, TCP ou autre. Ce n'est simplement pas toujours fait explicitement.

10
Brian White

Il "lie" un socket à une adresse, sinon il ne sait pas quelle adresse (paire adresse IP/port) il doit écouter.

Et bind peut également être utilisé côté client. Un exemple est sur un ordinateur avec plusieurs cartes réseau connectées au même réseau, mais le client veut seulement être vu comme venant d'une adresse réseau spécifique.

La liaison n'est pas seulement utilisée pour les sockets TCP, mais également pour les sockets UDP et d'autres protocoles.

8

Je sais que c'est une vieille question, mais j'ai une nouvelle réponse :)

Vous souhaiterez peut-être vous connecter à un serveur qui n'autorise qu'un nombre limité de connexions entrantes par adresse IP.

Si vous avez plusieurs cartes d’interface réseau (et donc plusieurs adresses sortantes possibles à partir desquelles vous connecter), vous pouvez utiliser bind (), en passant manuellement en revue chacun de vos ips, afin d’équilibrer vos connexions et ainsi disposer de plusieurs fois serait autrement autorisé.

Pour obtenir une liste de vos interfaces et ips, voir this answer.

0
BenGoldberg