-->

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

На нашем литературном портале можно бесплатно читать книгу UNIX: разработка сетевых приложений, Стивенс Уильям Ричард-- . Жанр: ОС и Сети. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале bazaknig.info.
UNIX: разработка сетевых приложений
Название: UNIX: разработка сетевых приложений
Дата добавления: 16 январь 2020
Количество просмотров: 386
Читать онлайн

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

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

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

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала

Перейти на страницу:

 1 #include "unp.h"

 2 #include <sys/param.h> /* макрос 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
требует подключения заголовочного файла
<sys/param.h>
.

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

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

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

10-22
 При работе со структурой
msghdr
и различными константами
MSG_<i>XXX</i>
мы встречаемся со множеством различий в реализациях. Одним из вариантов обработки таких различий может быть использование имеющейся в языке С возможности условного подключения (директива
#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 &lt; sizeof(struct cmsghdr) ||

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

41    return(n);

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

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

44 #ifdef IP_RECVDSTADDR

45    if (cmptr-&gt;cmsg_level == IPPROTO_IP &amp;&amp;

46     cmptr-&gt;cmsg_type == IP_RECVDSTADDR) {

47     memcpy(&amp;pktp-&gt;ipi_addr, CMSG_DATA(cmptr),

48      sizeof(struct in_addr));

49     continue;

50    }

51 #endif

52 #ifdef IP_RECVIF

53    if (cmptr-&gt;cmsg_level == IPPROTO_IP &amp;&amp; cmptr-&gt;cmsg_type == IP_RECVIF) {

54     struct sockaddr_dl *sdl;

55    sdl = (struct sockaddr_dl*)CMSG_DATA(cmptr);

56    pktp-&gt;ipi_ifindex = sdl-&gt;sdl_index;

57    continue;

58   }

59 #endif

60   err_quit(&quot;unknown ancillary data, len = %d,
level = %d, type = %d&quot;,

Перейти на страницу:
Комментариев (0)
название