С помощью присоединенного сокета UDP можно также задавать исходящий интерфейс, который будет использован для отправки дейтаграмм к определенному получателю. Это объясняется побочным эффектом функции
connect
, примененной к сокету UDP: ядро выбирает локальный IP-адрес (предполагается, что процесс еще не вызвал функцию
bind
для явного его задания). Локальный адрес выбирается в процессе поиска адреса получателя в таблице маршрутизации, причем берется основной IP-адрес
интерфейса, с которого, согласно таблице, будут отправляться дейтаграммы.
В листинге 8.13 показана простая программа UDP, которая с помощью функции connect соединяется с заданным IP-адресом и затем вызывает функцию
getsockname
, выводя локальный IP-адрес и порт.
Листинг 8.13. Программа UDP, использующая функцию connect для определения исходящего интерфейса
с несколькими сетевыми интерфейсами, то получим следующий вывод:
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.
8.15. Эхо-сервер TCP и UDP, использующий функцию select
Теперь мы объединим наш параллельный эхо-сервер TCP из главы 5 и наш последовательный эхо-сервер UDP из данной главы в один сервер, использующий функцию
select
для мультиплексирования сокетов TCP и UDP. В листинге 8.14 представлена первая часть этого сервера.
Листинг 8.14. Первая часть эхо-сервера, обрабатывающего сокеты TCP и UDP при помощи функции select