53-65
Окончательное формирование пакета требует построения заголовка IPv4 вызовом
libnet_build_ipv4
.
Библиотека libnet автоматически записывает поле ip_len в нужном порядке байтов. Это пример повышения переносимости программы благодаря использованию библиотек.
66-70
Мы вызываем функцию
libnet_write
для отправки подготовленной дейтаграммы в сеть.
Функция
send_dns_query
, использующая
libnet
, состоит всего из 67 строк, тогда как в версии, работавшей с символьными сокетами, общая длина кода составила 96 строк, в которых было по крайней мере 2 трюка, связанных с переносимостью.
29.8. Резюме
Символьные сокеты предоставляют возможность записывать и считывать IP-дейтаграммы, которые могут быть не поняты ядром, а доступ к канальному уровню позволяет считывать и записывать кадры канального уровня
tcpdump
— это, вероятно, наиболее широко используемая программа, имеющая непосредственный доступ к канальному уровню.
В различных операционных системах применяются различные способы доступа к канальному уровню. Мы рассмотрели пакетный фильтр Беркли, DLPI SVR4 и пакетные сокеты Linux (
SOCK_PACKET
). Но у нас имеется возможность, не вникая в различия перечисленных способов, использовать находящуюся в свободном доступе переносимую библиотеку захвата пакетов
libcap
.
Отправка символьных дейтаграмм осуществляется в разных системах по-разному. Свободно распространяемая библиотека
libnet
скрывает различия между системами и предоставляет интерфейс для вывода через символьные сокеты и непосредственно на канальном уровне.
Упражнения
1. Каково назначение флага
canjump
в листинге 29.7?
2. При работе программы
udpcksum
наиболее распространенным сообщением об ошибке является сообщение о недоступности порта ICMP (в пункте назначения не работает сервер имен) или недоступности узла ICMP. В обоих случаях нам не нужно ждать истечения времени ожидания, заданного функцией
udp_read
в листинге 29.6, так как сообщение о подобной ошибке фактически является ответом на наш запрос DNS. Модифицируйте программу таким образом, чтобы она перехватывала эти ошибки ICMP.
Глава 30
Альтернативное устройство клиента и сервера
30.1. Введение
При написании сервера под Unix мы можем выбирать из следующих вариантов управления процессом:
Наш первый сервер, показанный в листинге 1.5, был
В листинге 5.1 показан первый в данной книге
fork
. Традиционно большинство серверов, работающих под Unix, попадают в эту категорию.
В разделе 6.8 мы разработали другую версию сервера TCP, в котором имеется только один процесс, обрабатывающий любое количество клиентских запросов с помощью функции
select
.
В листинге 26.2 мы модифицировали параллельный сервер, создав для каждого клиента по одному потоку вместо одного процесса.
В этой главе мы рассмотрим два других способа модификации устройства параллельного сервера.
fork
, которая создает определенное количество (пул) дочерних процессов. Обработкой очередного клиентского запроса занимается процесс, взятый из этого набора.
В данной главе мы будем рассматривать множество вопросов, связанных с предварительным созданием потоков и процессов. Например, что произойдет, если в пуле окажется недостаточное количество процессов или потоков? А если их будет слишком много? Как родительский и дочерние процессы (или потоки) синхронизируют свои действия?
Обычно написать клиент легче, чем сервер, за счет простоты управления процессом клиента. Тем не менее мы уже исследовали различные способы написания простого эхо-клиента, которые вкратце изложены в разделе 30.2.