8.10. Итоговый пример клиент-сервера UDP
8.10. Итоговый пример клиент-сервера UDP
На рис. 8.5 крупными черными точками показаны четыре значения, которые должны быть заданы или выбраны, когда клиент отправляет дейтаграмму UDP.
Рис. 8.5. Обобщение модели клиент-сервер UDP с точки зрения клиента
Клиент должен задать IP-адрес сервера и номер порта для вызова функции sendto. Обычно клиентский IP-адрес и номер порта автоматически выбираются ядром, хотя мы отмечали, что клиент может вызвать функцию bind. Мы также отмечали, что если эти два значения выбираются для клиента ядром, то динамически назначаемый порт клиента выбирается один раз — при первом вызове функции sendto, и более никогда не изменяется. Однако IP-адрес клиента может меняться для каждой дейтаграммы UDP, которую отправляет клиент, если предположить, что клиент не связывает с сокетом определенный IP-адрес при помощи функции bind. Причину объясняет рис. 8.5: если узел клиента имеет несколько сетевых интерфейсов, клиент может переключаться между ними (на рис. 8.5 один адрес относится к канальному уровню, изображенному слева, другой — к изображенному справа). В худшем варианте этого сценария IP-адрес клиента, выбираемый ядром на основе исходящего канального уровня, будет меняться для каждой дейтаграммы.
Что произойдет, если клиент с помощью функции bind свяжет IP-адрес со своим сокетом, но ядро решит, что исходящая дейтаграмма должна быть отправлена с какого-то другого канального уровня? В этом случае дейтаграмма IP будет содержать IP-адрес отправителя, отличный от IP-адреса исходящего канального уровня (см. упражнение 8.6).
На рис. 8.6 представлены те же четыре значения, но с точки зрения сервера.
Рис. 8.6. Обобщение модели клиент-сервер UDP с точки зрения сервера
Сервер может узнать по крайней мере четыре параметра для каждой полученной дейтаграммы: IP-адрес отправителя, IP-адрес получателя, номер порта отправителя и номер порта получателя. Вызовы, возвращающие эти сведения серверам TCP и UDP, приведены в табл. 8.1.
Таблица 8.1. Информация, доступная серверу из приходящей дейтаграммы IP
IP-дейтаграмма клиента TCP-сервер UDP-сервер IP-адрес отправителя accept recvfrom Номер порта отправителя accept recvfrom IP-адрес получателя getsockname recvmsg Номер порта получателя getsockname getsocknameУ сервера TCP всегда есть простой доступ ко всем четырем фрагментам информации для присоединенного сокета, и эти четыре значения остаются постоянными в течение всего времени жизни соединения. Однако в случае соединения UDP IP-адрес получателя можно получить только с помощью установки параметра сокета IP_RECVDSTADDR для IPv4 или IPV6_PKTINFO для IPv6 и последующего вызова функции recvmsg вместо функции recvfrom. Поскольку протокол UDP не ориентирован на установление соединения, IP-адрес получателя может меняться для каждой дейтаграммы, отправляемой серверу. Сервер UDP может также получать дейтаграммы, предназначенные для одного из широковещательных адресов узла или для адреса многоадресной передачи, что мы обсуждаем в главах 20 и 21. Мы покажем, как определить адрес получателя дейтаграммы UDP, в разделе 20.2, после того как опишем функцию recvmsg.
Данный текст является ознакомительным фрагментом.