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

Пример: вывод 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)");

46 #endif

47 #ifdef MSG_MCAST

48   if (flags & MSG_MCAST)

49    printf(" (multicast)");

50 #endif

51   printf(" ");

52   Sendto(sockfd, mesg, n, 0, pcliaddr, len);

53  }

54 }

Изменение MAXLINE

2-3 Мы удаляем существующее определение MAXLINE, имеющееся в нашем заголовочном файле unp.h, и задаем новое значение — 20. Это позволит нам увидеть, что произойдет, когда мы получим дейтаграмму UDP, превосходящую размер буфера, переданного функции (в данном случае функции recvmsg).

Установка параметров сокета IP_RECVDSTADDR и IP_RECVIF

14-21 Если параметр сокета IP_RECVDSTADDR определен, мы включаем его. Аналогично включается параметр сокета IP_RECVIF.

Чтение дейтаграммы, вывод IP-адреса отправителя и порта

24-28 Дейтаграмма читается с помощью вызова функции recvfrom_flags. IP-адрес отправителя и порт ответа сервера преобразуются в формат представления функцией sock_ntop.

Вывод IP-адреса получателя

29-31 Если возвращаемый IP-адрес ненулевой, он преобразуется в формат представления функцией inet_ntop и выводится.

Вывод имени интерфейса, на котором была получена дейтаграмма

32-34 Если индекс интерфейса ненулевой, его имя будет возвращено функцией if_indextoname. Это имя наша функция печатает на экране.

Проверка различных флагов

35-51 Мы проверяем четыре дополнительных флага и выводим сообщение, если какие-либо из них установлены.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Дейтаграммы

Из книги Искусство программирования на языке сценариев командной оболочки автора Купер Мендель

Дейтаграммы Дейтаграммы аналогичны почтовым ящикам и используются при сходных обстоятельствах. Соединение между отправителем и получателем отсутствует, а получателей может быть несколько. Ни почтовые ящики, ни дейтаграммы не гарантируют доставку данных получателю, а


12.14 Пример файла трансляции имен в адреса

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

12.14 Пример файла трансляции имен в адреса Рис. 12.6 демонстрирует файл трансляции имен в адреса для нашего мифического домена fishfood.com. Файл содержит несколько комментариев, которые отмечены символом точки с запятой


11.5.2. Модификация флага "закрыть при выполнении"

Из книги автора

11.5.2. Модификация флага "закрыть при выполнении" Во время системного вызова exec() дескрипторы файлов обычно остаются открытыми для использования в новых программах. В некоторых случаях может потребоваться, чтобы файлы закрывались, когда вызывается exec(). Вместо закрытия их


Пример 9-6. arglist: Вывод списка аргументов с помощью переменных $* и $@

Из книги автора

Пример 9-6. arglist: Вывод списка аргументов с помощью переменных $* и $@ #!/bin/bash# Вызовите сценарий с несколькими аргументами, например: "один два три".E_BADARGS=65if [ ! -n "$1" ]then echo "Порядок использования: `basename $0` argument1 argument2 и т.д." exit $E_BADARGSfiechoindex=1echo "Список аргументов в переменной "$*":"for arg in


Пример 17-4. Вывод многострочных сообщений с подавлением символов табуляции

Из книги автора

Пример 17-4. Вывод многострочных сообщений с подавлением символов табуляции #!/bin/bash# То же, что и предыдущий сценарий, но...# Символ "-", начинающий строку-ограничитель встроенного документа: <<-# подавляет вывод символов табуляции, которые могут встречаться в теле


Пример: функция str_echo, использующая стандартный ввод-вывод

Из книги автора

Пример: функция str_echo, использующая стандартный ввод-вывод Сейчас мы модифицируем наш эхо-сервер TCP (см. листинг 5.2) для использования стандартного ввода-вывода вместо функций readline и writen. В листинге 14.6 представлена версия нашей функции str_echo, использующая стандартный


Пример: вывод аппаратного адреса узла

Из книги автора

Пример: вывод аппаратного адреса узла Теперь мы используем нашу функцию my_addrs для того, чтобы возвратить все IP-адреса узла. Затем для каждого IP-адреса мы делаем вызов SIOCGARP функции ioctl, чтобы получить и вывести аппаратные адреса. Наша программа показана в


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

Из книги автора

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


22.3. Обрезанные дейтаграммы

Из книги автора

22.3. Обрезанные дейтаграммы В системах, происходящих от BSD, при получении UDP-дейтаграммы, размер которой больше буфера приложения, функция recvmsg устанавливает флаг MSG_TRUNC в элементе msg_flags структуры msghdr (см. табл. 14.2). Все Беркли-реализации, поддерживающие структуру msghdr с