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

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

Шрифт:

Рис. 22.1. Объект вспомогательных данных, возвращаемый для параметра IP_RECVIF

Вспомните структуру адреса сокета канального уровня (см. листинг 18.1). Данные, возвращаемые в объекте вспомогательных данных, представлены в одной из этих структур, но длины трех элементов являются нулевыми (длина имени, адреса и селектора). Следовательно, нет никакой необходимости указывать эти значения, и таким образом структура имеет размер 8 байт, а не 20, как было в листинге 18.1. Возвращаемая нами информация — это индекс интерфейса.

Пример: вывод IP-адреса получателя и флага обрезки дейтаграммы

Для проверки нашей функции мы изменим функцию

dg_echo
(см. листинг 8.2) так, чтобы она вызывала функцию
recvfrom_flags
вместо функции recvfrom. Новая версия функции
dg_echo
показана в листинге 22.3.

Листинг 22.3. Функция dg_echo, вызывающая нашу функцию recvfrom_flags

//advio/dgechoaddr.c

1 #include "unpifi.h"

2 #undef MAXLINE

3 #define MAXLINE 20 /* устанавливаем новое значение, чтобы

пронаблюдать обрезку дейтаграмм */

4 void

5 dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)

6 {

7 int flags;

8 const int on = 1;

9 socklen_t len;

10 ssize_t n;

11 char
mesg[MAXLINE], str[INET6_ADDRSTRLEN], ifname[IFNAMSIZ];

12 struct in_addr in_zero;

13 struct in_pktinfo pktinfo;

14 #ifdef IP_RECVDSTADDR

15 if (setsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on)) < 0)

16 err_ret("setsockopt of IP_RECVDSTADDR");

17 #endif

18 #ifdef IP_RECVIF

19 if (setsockopt(sockfd, IPPROTO_IP, IP_RECVIF, &on, sizeof(on)) < 0)

20 err_ret("setsockopt of IP_RECVIF");

21 #endif

22 bzero(&in_zero, sizeof(struct in_addr)); /* IPv4-адрес, состоящий

из одних нулей */

23 for (;;) {

24 len = clilen;

25 flags = 0;

26 n = Recvfrom_flags(sockfd, mesg, MAXLINE, &flags,

27 pcliaddr, &len, &pktinfo);

28 printf("%d-byte datagram from %s", n, Sock_ntop(pcliaddr, len));

29 if (memcmp(&pktinfo.ipi_addr, &in_zero, sizeof(in_zero)) != 0)

30 printf(", to %s", Inet_ntop(AF_INET, &pktinfo.ipi_addr,

31 str, sizeof(str)));

32 if (pktinfo.ipi_ifindex > 0)

33 printf(", recv i/f = %s",

34 If_indextoname(pktinfо.ipi_ifindex, ifname));

35 #ifdef MSG_TRUNC

36 if (flags & MSG_TRUNC)

37 printf(" (datagram truncated)");

38 #endif

39 #ifdef MSG_CTRUNC

40 if (flags & MSG_CTRUNC)

41 printf(" (control info truncated)");

42 #endif

43 #ifdef MSG_BCAST

44 if (flags & MSG_BCAST)

45 printf(" (broadcast)");

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

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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