Книга: UNIX: разработка сетевых приложений
Пример: вывод 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 charmesg[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("n");
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
Мы проверяем четыре дополнительных флага и выводим сообщение, если какие-либо из них установлены.
- 22.2. Получение флагов, IP-адреса получателя и индекса интерфейса
- Пример установочного скрипта
- Пример из практики
- ПРИМЕР ПРОСТОЙ ПРОГРАММЫ НА ЯЗЫКЕ СИ
- Включение и отключение синхронного вывода
- Примеры получения статистики
- Пример применения метода «пять почему»
- Пример 12-8. Частота встречаемости отдельных слов
- 1.2.5. Пример программы
- Пример 17-10. Блочный комментарий
- Примеры
- Глава 2 Обнаружение адреса