Книга: UNIX: разработка сетевых приложений

8.14. Определение исходящего интерфейса для UDP

8.14. Определение исходящего интерфейса для UDP

С помощью присоединенного сокета UDP можно также задавать исходящий интерфейс, который будет использован для отправки дейтаграмм к определенному получателю. Это объясняется побочным эффектом функции connect, примененной к сокету UDP: ядро выбирает локальный IP-адрес (предполагается, что процесс еще не вызвал функцию bind для явного его задания). Локальный адрес выбирается в процессе поиска адреса получателя в таблице маршрутизации, причем берется основной IP-адрес интерфейса, с которого, согласно таблице, будут отправляться дейтаграммы.

В листинге 8.13 показана простая программа UDP, которая с помощью функции connect соединяется с заданным IP-адресом и затем вызывает функцию getsockname, выводя локальный IP-адрес и порт.

Листинг 8.13. Программа UDP, использующая функцию connect для определения исходящего интерфейса

//udpcliserv/udpcli09.c
 1 #include "unp.h"
 2 int
 3 main(int argc, char **argv)
 4 {
 5  int sockfd;
 6  socklen_t len;
 7  struct sockaddr_in cliaddr, servaddr;
 8  if (argc != 2)
 9   err_quit("usage: udpcli <Ipaddress>");
10  sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
11  bzero(&servaddr, sizeof(servaddr));
12  servaddr.sin_family = AF_INET;
13  servaddr.sin_port = htons(SERV_PORT);
14  Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
15  Connect(sockfd, (SA*)&servaddr, sizeof(servaddr));
16  len = sizeof(cliaddr);
17  Getsockname(sockfd, (SA*)&cliaddr, &len);
18  printf("local address %sn", Sock_ntop((SA*)&cliaddr, len));
19  exit(0);
20 }

Если мы запустим программу на узле freebsd с несколькими сетевыми интерфейсами, то получим следующий вывод:

freebsd % udpcli09 206.168.112.96
local address 12.106.32.254:52329
freebsd % udpcli09 192.168.42.2
local address 192.168.42.1:52330
freebsd % udpcli09 127.0.0.1
local address 127.0.0.1:52331

По рис. 1.7 видно, что когда мы запускаем программу первые два раза, аргументом командной строки является IP-адрес в разных сетях Ethernet. Ядро присваивает локальный IP-адрес первичному адресу интерфейса в соответствующей сети Ethernet. При вызове функции connect на сокете UDP ничего не отправляется на этот узел — это полностью локальная операция, которая сохраняет IP-адрес и порт собеседника. Мы также видим, что вызов функции connect на неприсоединенном сокете UDP также присваивает сокету динамически назначаемый порт.

ПРИМЕЧАНИЕ

К сожалению, эта технология действует не во всех реализациях, что особенно касается ядер, происходящих от SVR4. Например, это не работает в Solaris 2.5, но работает в AIX, Digital Unix, Linux, MacOS X и Solaris 2.6.

Оглавление книги


Генерация: 1.754. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз