Уильям Стивенс - UNIX: разработка сетевых приложений

Тут можно читать онлайн Уильям Стивенс - UNIX: разработка сетевых приложений - бесплатно ознакомительный отрывок. Жанр: comp-osnet, издательство Питер, год 2007. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    UNIX: разработка сетевых приложений
  • Автор:
  • Жанр:
  • Издательство:
    Питер
  • Год:
    2007
  • Город:
    Санкт-Петербург
  • ISBN:
    5-94723-991-4
  • Рейтинг:
    4.33/5. Голосов: 91
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

Уильям Стивенс - UNIX: разработка сетевых приложений краткое содержание

UNIX: разработка сетевых приложений - описание и краткое содержание, автор Уильям Стивенс, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.

UNIX: разработка сетевых приложений - читать онлайн бесплатно ознакомительный отрывок

UNIX: разработка сетевых приложений - читать книгу онлайн бесплатно (ознакомительный отрывок), автор Уильям Стивенс
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

В завершение этой главы мы рассмотрим информацию о пакете, которая может быть передана во вспомогательных данных дейтаграммы IPv6: IP-адрес отправителя, отправляющий интерфейс, предельное количество транзитных узлов исходящих дейтаграмм и адрес следующего транзитного узла. Аналогичная информация — IP-адрес получателя, принимающий интерфейс и предельное количество транзитных узлов — может быть получена вместе с дейтаграммой IPv6.

22.2. Получение флагов, IP-адреса получателя и индекса интерфейса

Исторически функции sendmsgи recvmsgиспользовались только для передачи дескрипторов через доменные сокеты Unix (см. раздел 15.7), но даже это происходило сравнительно редко. Однако в настоящее время популярность этих двух функций растет по двум причинам:

1. Элемент msg_flags, добавленный в структуру msghdrв реализации 4.3BSD Reno, возвращает приложению флаги сообщения. Эти флаги мы перечислили в табл. 14.2.

2. Вспомогательные данные используются для передачи все большего количества информации между приложением и ядром. В главе 27 мы увидим, что IPv6 продолжает эту тенденцию.

В качестве примера использования функции recvmsgмы напишем функцию recvfrom_flags, аналогичную функции recvfrom, но дополнительно позволяющую получить:

■ возвращаемое значение msg_flags;

■ адрес получателя полученной дейтаграммы (из параметра сокета IP_RECVDSTADDR);

■ индекс интерфейса, на котором была получена дейтаграмма (параметр сокета IP_RECVIF).

Чтобы можно было получить два последних элемента, мы определяем в нашем заголовке unp.hследующую структуру:

struct in_pktinfo {

struct in_addr ipi_addr; /* IPv4-адрес получателя */

int ipi_ifindex; /* индекс интерфейса, на котором была

получена дейтаграмма */

};

Мы выбрали имена структуры и ее элементов так, чтобы получить определенное сходство со структурой IPv6 in6_pktinfo, возвращающей те же два элемента для сокета IPv6 (см. раздел 22.8). Наша функция recvfrom_flagsбудет получать в качестве аргумента указатель на структуру in_pktinfo, и если этот указатель не нулевой, возвращать структуру через указатель.

Проблема построения этой структуры состоит в том, что неясно, что возвращать, если недоступна информация, которая должна быть получена из параметра сокета IP_RECVDSTADDR(то есть реализация не поддерживает данный параметр сокета). Обработать индекс интерфейса легко, поскольку нулевое значение может использоваться как указание на то, что индекс неизвестен. Но для IP-адреса все 32-разрядные значения являются действительными. Мы выбрали такое решение: адрес получателя 0.0.0.0 возвращается в том случае, когда действительное значение недоступно. Хотя это реальный IP-адрес, использовать его в качестве IP-адреса получателя не разрешается (RFC 1122 [10]). Он будет действителен только в качестве IP-адреса отправителя во время начальной загрузки узла, когда узел еще не знает своего IP-адреса.

ПРИМЕЧАНИЕ

К сожалению, Беркли-ядра принимают дейтаграммы, предназначенные для адреса 0.0.0.0 [128, с. 218-219]. Это устаревшие адреса широковещательной передачи, генерируемые ядрами 4.2BSD.

Первая часть нашей функции recvfrom_flagsпредставлена в листинге 22.1 [1] Все исходные коды программ, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com. . Эта функция предназначена для использования с сокетом UDP.

Листинг 22.1. Функция recvfrom_flags: вызов функции recvmsg

//adviо/recvfromflags.c

1 #include "unp.h"

2 #include /* макрос ALIGN для макроса CMSG_NXTHDR() */

3 ssize_t

4 recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,

5 SA *sa, socklen_t *salenptr, struct unp_in_pktinfo *pktp)

6 {

7 struct msghdr msg;

8 struct iovec iov[1];

9 ssize_t n;

10 #ifdef HAVE_MSGHDR_MSG_CONTROL

11 struct cmsghdr *cmptr;

12 union {

13 struct cmsghdr cm;

14 char control[CMSG_SPACE(sizeof(struct in_addr)) +

15 CMSG_SPACE(sizeof(struct unp_in_pktinfo))];

16 } control_un;

17 msg.msg_control = control_un.control;

18 msg.msg_controllen = sizeof(control_un.control);

19 msg.msg_flags = 0;

20 #else

21 bzero(&msg, sizeof(msg)); /* обнуление msg_accrightslen = 0 */

22 #endif

23 msg.msg_name = sa;

24 msg.msg_namelen = *salenptr;

25 iov[0].iov_base = ptr;

26 iov[0].iov_len = nbytes;

27 msg.msg_iov = iov;

28 msg.msg_iovlen = 1;

29 if ((n = recvmsg(fd, &msg, *flagsp)) < 0)

30 return(n);

31 *salenptr = msg.msg_namelen; /* возвращение результатов */

32 if (pktp)

33 bzero(pktp, sizeof(struct unp_in_pktinfo)); /* 0.0.0.0. интерфейс = 0 */

Подключаемые файлы

1-2 Использование макроопределения CMSG_NXTHDRтребует подключения заголовочного файла .

Аргументы функции

3-5 Аргументы функции аналогичны аргументам функции recvfromза исключением того, что четвертый аргумент является указателем на целочисленный флаг (так что мы можем возвратить флаги, возвращаемые функцией recvmsg), а седьмой аргумент новый: это указатель на структуру unp_in_pktinfo, содержащую IPv4-адрес получателя пришедшей дейтаграммы и индекс интерфейса, на котором дейтаграмма была получена.

Различия реализаций

10-22 При работе со структурой msghdrи различными константами MSG_ XXX мы встречаемся со множеством различий в реализациях. Одним из вариантов обработки таких различий может быть использование имеющейся в языке С возможности условного подключения (директива #ifdef). Если реализация поддерживает элемент msg_control, то выделяется пространство для хранения значений, возвращаемых параметрами сокета IP_RECVDSTADDRи IP_RECVIF, и соответствующие элементы инициализируются.

Заполнение структуры msghdr и вызов функции recvmsg

23-33 Заполняется структура msghdrи вызывается функция recvmsg. Значения элементов msg_namelenи msg_flagsдолжны быть переданы обратно вызывающему процессу. Они являются аргументами типа «значение-результат». Мы также инициализируем структуру вызывающего процесса unp_in_pktinfo, устанавливая IP-адрес 0.0.0.0 и индекс интерфейса 0.

В листинге 22.2 показана вторая часть нашей функции.

Листинг 22.2. Функция recvfrom_flags: возвращаемые флаги и адрес получателя

//advio/recvfromflags.c

34 #ifndef HAVE_MSGHDR_MSG_CONTROL

35 *flagsp = 0; /* возвращение результатов */

36 return(n);

37 #else

38 *flagsp = msg.msg_flags; /* возвращение результатов */

39 if (msg.msg_controllen < sizeof(struct cmsghdr) ||

40 (msg.msg_flags & MSG_CTRUNC) || pktp == NULL)

41 return(n);

42 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL;

43 cmptr = CMSG_NXTHDR(&msg, cmptr)) {

44 #ifdef IP_RECVDSTADDR

45 if (cmptr->cmsg_level == IPPROTO_IP &&

46 cmptr->cmsg_type == IP_RECVDSTADDR) {

47 memcpy(&pktp->ipi_addr, CMSG_DATA(cmptr),

48 sizeof(struct in_addr));

49 continue;

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Уильям Стивенс читать все книги автора по порядку

Уильям Стивенс - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




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


Отзывы читателей о книге UNIX: разработка сетевых приложений, автор: Уильям Стивенс. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x