web-dev-qa-db-fra.com

Comment un socket sait-il quel contrôleur d'interface réseau utiliser?

Si un ordinateur possède plusieurs cartes réseau, toutes connectées à différents réseaux et fonctionnant correctement, lorsque nous ouvrons un socket, comment le système d'exploitation détermine-t-il quelle NIC utiliser avec cette socket? L'API nous permet de spécifier explicitement le NIC qui doit être utilisé?

46
user500944

Je ne sais pas pourquoi je suis inclus dans la suggestion de modification alors que je n'étais même pas lié à cette question. J'ai déjà reçu une suggestion de modification similaire ... cela pourrait être un bug/problème.

(Si vous vous sentez enclin à voter, la réponse de @ Shtééf le mérite plus que la mienne.)

Cela dépend de la connexion ou de la liaison.

Si vous vous liez, vous pouvez vous lier à une adresse IP spécifique correspondant à l'une des interfaces de la machine, ou vous pouvez vous lier à 0.0.0.0, auquel cas le socket écoutera sur toutes les interfaces.

Si vous connectez un socket non lié, les tables de routage de la machine, conjointement avec l'adresse IP de destination, détermineront sur quelle interface la demande de connexion sera exécutée.

Il est possible de lier une prise puis de la connecter. Dans ce cas, le socket restera lié conformément à l'appel de liaison lorsqu'il établira la connexion. (Merci à @RemyLebeau de l'avoir signalé.)

31
Marcelo Cantos

J'écris ceci dans une perspective Linux, mais je suppose que cela s'applique partout.

La décision est prise lorsque le socket est lié. Lorsque bind est appelé, l'adresse que vous spécifiez détermine l'interface sur laquelle le socket écoutera. (Ou même toutes les interfaces.)

Même si vous n'utilisez pas bind, cela se produit implicitement lorsque vous connect. La destination est recherchée dans la table de routage, qui doit contenir un itinéraire vers le réseau de destination. L'itinéraire contient également l'interface à utiliser et peut éventuellement spécifier l'adresse source. Si aucune adresse source n'est spécifiée, l'adresse principale de l'interface est prise.

Vous pouvez réellement utiliser bind avec connect, pour forcer votre connexion sortante à utiliser une adresse et un port spécifiques. Un socket doit toujours avoir ces deux bits d'information, donc même si vous n'en avez pas, l'adresse principale est utilisée et un port aléatoire est choisi.

52
Stéphan Kochen

Je ne sais pas vraiment quelle méthode est la meilleure, mais il existe une théorie alternative à l'approche bind () - avant-connexion () que Shtééf a présentée. C'est d'utiliser setsockopt () avec SO_BINDTODEVICE. Voir: http://codingrelic.geekhold.com/2009/10/code-snippet-sobindtodevice.html

0
Ph0t0n