Вход/Регистрация
UNIX: разработка сетевых приложений
вернуться

Стивенс Уильям Ричард

Шрифт:

};

Мы выбрали имена структуры и ее элементов так, чтобы получить определенное сходство со структурой 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] . Эта функция предназначена для использования с сокетом UDP.

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

1

Все исходные коды программ, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com.

//adviо/recvfromflags.c

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_ XXX
мы встречаемся со множеством различий в реализациях. Одним из вариантов обработки таких различий может быть использование имеющейся в языке С возможности условного подключения (директива
#ifdef
). Если реализация поддерживает элемент
msg_control
, то выделяется пространство для хранения значений, возвращаемых параметрами сокета
IP_RECVDSTADDR
и
IP_RECVIF
, и соответствующие элементы инициализируются.

  • Читать дальше
  • 1
  • ...
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: