У машины есть 2 сетевых карты. Какой будет использоваться при подключении к сокету? - PullRequest
7 голосов
/ 09 января 2009

Предположим, я создаю очень простое сокетное соединение, как можно программно:

  1. Узнайте, какой интерфейс (IP-адрес / NIC) используется.
  2. Принудительно использовать другой интерфейс

Ответы [ 3 ]

13 голосов
/ 09 января 2009

Какой бы язык вы ни использовали, в конечном итоге вы будете использовать библиотеку сокетов, наложенную поверх реализации исходной сетевой библиотеки BSD sockets C. Хотя вам может потребоваться изменить некоторые вещи для разных библиотек и языков, следующая информация должна по крайней мере помочь определить, где искать в документации вашей библиотеки.

Серверы

Обычно серверная программа выполняет следующую последовательность вызовов:

  1. socket() возвращает «плавающий» объект сокета.
  2. bind() привязывает сокет к определенному общеизвестному номеру порта на (обычно) всех сетевых интерфейсных платах (NIC) в машине.
  3. listen() заставляет сокет работать "вживую".
  4. accept() блокируется до тех пор, пока не будет установлено соединение с клиентским компьютером.

Точка, в которой вы можете решить, какой сетевой адаптер использовать при вызове bind(), предполагает наличие структуры данных, содержащей IP-адрес и номер порта. Обычная стратегия состоит в том, чтобы передать специальное значение INADDR_ANY для IP-адреса, указывающее, что соединения должны использовать любые и все NIC в машине, однако вместо этого можно указать IP-адрес конкретного NIC для получения соединений только через этот NIC.

Клиенты

Обычно клиентская программа выполняет следующую последовательность вызовов:

  1. socket() возвращает «плавающий» объект сокета.
  2. connect() привязывает сокет к случайно выбранному порту на случайно выбранном сетевом адаптере и пытается подключиться к указанной удаленной комбинации host:port.

Так как же клиент может выбрать, какой сетевой адаптер использовать? Клиент также может выбрать bind(), если он того пожелает, после socket() и до connect(). Обычно это не делается просто потому, что connect() автоматически связывает несвязанный сокет таким образом, чтобы разрешить доступ через любую сетевую карту (что обычно является желаемым поведением), но это автоматическое связывание можно отключить, явно вызвав bind() , В этом случае вы должны указать 0 для номера порта, чтобы ОС выбрала случайный номер порта для вас.

После установления соединения вы можете позвонить по номеру getsockname(), чтобы получить информацию о сокете, например, к какому IP-адресу он привязан (т. Е. Через какой сетевой адаптер он связывается) и какой номер порта был назначен (в случае клиентской программы).

2 голосов
/ 09 января 2009

а. После того, как соединение установлено, большинство API сокетов вызывают что-то вроде «getLocalAddress», которое сообщает вам интерфейс, который выбрала ОС для вас.

б. Аналогично, после создания сокета, но до установления соединения, большинство API сокетов имеют вызов для привязки сокета к локальному адресу и / или порту.

1 голос
/ 09 января 2009

Эти ссылки окажутся полезными, поскольку в вопросе не указан язык, здесь приведены наиболее распространенные.

Программирование сокетов на C

Программирование сокетов на C #

Программирование сокетов в Java

Программирование сокетов в Python

Итак, воспользуйтесь любой из этих ссылок и перейдите на используемый вами язык. Найдите функцию для получения вашего адреса хоста или IP-адреса и используйте метод Bind для соответствующего языка. Это заставит приложение связываться с этим интерфейсом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...