UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Определение «длительное время» означает, что другой клиент вынужден ждать в течение некоторого заметного для него промежутка времени, пока обслуживается текущий клиент. Например, если два клиентских запроса приходят в течение 10 мс и предоставление сервиса каждому клиенту занимает в среднем 5 с, то второй клиент будет вынужден ждать ответа около 10 с вместо 5 с (если бы запрос был принят в обработку сразу же по прибытии).
В случае TCP проблема решается просто — требуется лишь породить дочерний процесс с помощью функции
fork
1. Первый тип — простой сервер UDP, который читает клиентский запрос, посылает ответ и затем завершает работу с клиентом. В этом сценарии сервер, читающий запрос клиента, может с помощью функции
fork
fork
2. Второй тип — сервер UDP, обменивающийся множеством дейтаграмм с клиентом. Проблема здесь в том, что единственный номер порта сервера, известный клиенту, — это номер заранее известного порта. Клиент посылает первую дейтаграмму своего запроса на этот порт, но как сервер сможет отличить последующие дейтаграммы этого клиента от запросов новых клиентов? Типичным решением этой проблемы для сервера будет создание нового сокета для каждого клиента, связывание при помощи функции
bind
Примером второго типа сервера UDP является сервер TFTP (Trivial File Transfer Protocol — упрощенный протокол передачи файлов). Передача файла с помощью TFTP обычно требует большого числа дейтаграмм (сотен или тысяч, в зависимости от размера файла), поскольку этот протокол отправляет в одной дейтаграмме только 512 байт. Клиент отправляет дейтаграмму на известный порт сервера (69), указывая, какой файл нужно отправить или получить. Сервер читает запрос, но отправляет ответ с другого сокета, который он создает и связывает с динамически назначаемым портом. Все последующие дейтаграммы между клиентом и сервером используют для передачи этого файла новый сокет. Это позволяет главному серверу TFTP продолжать обработку других клиентских запросов, приходящих на порт 69, в то время как происходит передача файла (возможно, в течение нескольких секунд или даже минут).
Если мы рассмотрим автономный сервер TFTP (то есть случай, когда не используется демон
inetd
Рис. 22.3. Процессы, происходящие на автономном параллельном UDP-сервере
Если используется демон
inetd
wait-flag
wait
inetd
select
Рис. 22.4. Параллельный сервер UDP, запущенный демоном inetd
Сервер TFTP, являясь дочерним процессом функции
inetd
recvfrom
fork
exit
inetd
SIGCHLD
inetd
select
22.8. Информация о пакетах IPv6
IPv6 позволяет приложению определять до пяти характеристик исходящей дейтаграммы:
■ IPv6-адрес отправителя;
■ индекс интерфейса для исходящих дейтаграмм;
■ предельное количество транзитных узлов для исходящих дейтаграмм;
■ адрес следующего транзитного узла;
■ класс исходящего трафика.
Эта информация отправляется в виде вспомогательных данных с функцией
sendmsg
Для полученного пакета могут быть возвращены четыре аналогичных характеристики. Они возвращаются в виде вспомогательных данных с функцией
recvmsg
■ IPv6-адрес получателя;
■ индекс интерфейса для входящих дейтаграмм;
■ предельное количество транзитных узлов для входящих дейтаграмм.
■ класс входящего трафика.
На рис. 22.5 показано содержимое вспомогательных данных, о которых рассказывается далее.
Рис. 22.5. Вспомогательные данные для информации о пакете IPv6
Структура
in6_pktinfo
struct in6_pktinfo {
struct in6_addr ipi6_addr; /* IPv6-адрес отправителя/получателя */
int ipi6_ifindex; /* индекс интерфейса для исходящей/получаемой дейтаграммы */
};
Эта структура определяется в заголовочном файле
<netinet/in.h>
cmsghdr
cmsg_level
IPPROTO_IPV6
cmsg_type
IPV6_PKTINFO
in6_pktinfo
cmsghdr
Чтобы отправить эту информацию, никаких специальных действий не требуется — нужно только задать управляющую информацию во вспомогательных данных функции
sendmsg
IPV6_PKTINFO
in6_pktinfo
recvmsg
IPV6_RECVPKTINFO