UNIX: разработка сетевых приложений
Шрифт:
Обработка ответов осуществляется функцией
readlоор
, представленной в листинге 28.4. Листинг 28.4. Функция readloop
//ping/readlоор.c
1 #include "ping.h"
2 void
3 readloop(void)
4 {
5 int size;
6 char recvbuf[BUFSIZE];
7 char controlbuf[BUFSIZE];
8 struct msghdr msg;
9 struct iovec iov;
10 ssize_t n;
11 struct timeval tval;
12 sockfd = Socket(pr->sasend->sa_family, SOCK_RAW, pr->icmpproto);
13 setuid(getuid); /*
права привилегированного пользователя
больше не нужны */
14 if (pr->finit)
15 (*pr->finit);
16 size = 60 * 1024; /* setsockopt может завершиться с ошибкой */
17 setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
18 sig_alrm(SIGALRM); /* отправка первого пакета */
19 iov.iov_base = recvbuf;
20 iov.iov_len = sizeof(recvbuf);
21 msg.msg_name = pr->sarecv;
22 msg.msg_iov = &iov;
23 msg.msg_iovlen = 1;
24 msg.msg_control = controlbuf;
25 for (;;) {
26 msg.msg_namelen = pr->salen;
27 msg.msg_controllen = sizeof(controlbuf);
28 n = recvmsg(sockfd, &msg, 0);
29 if (n < 0) {
30 if (errno == EINTR)
31 continue;
32 else
33 err_sys("recvmsg error");
24 }
35 Gettimeofday(&tval, NULL);
36 (*pr->fproc)(recvbuf, n, &msg, &tval);
37 }
38 }
Создание сокета
12-13
Создается символьный сокет, соответствующий выбранному протоколу. В вызове функции setuid
нашему эффективному идентификатору пользователя присваивается фактический идентификатор пользователя. Для создания символьных сокетов программа должна иметь права привилегированного пользователя, но когда символьный сокет уже создан, от этих прав можно отказаться. Всегда разумнее отказаться от лишних прав, если в них нет необходимости, например на тот случай, если в программе есть скрытая ошибка, которой кто-либо может воспользоваться. Выполнение инициализации для протокола
14-15
Мы выполняем функцию инициализации для выбранного протокола. Для IPv6 такая функция представлена в листинге 28.7. Установка размера приемного буфера сокета
16-17
Пытаемся установить размер приемного буфера сокета, равный 61 440 байт (60x1024) — этот размер больше задаваемого по умолчанию. Это делается в расчете на случай, когда пользователь проверяет качество связи с помощью программы ping
, обращаясь либо к широковещательному адресу IPv4, либо к групповому адресу. В обоих случаях может быть получено большое количество ответов. Увеличивая размер буфера, мы уменьшаем вероятность того, что приемный буфер переполнится. Отправка первого пакета
18
Запускаем обработчик сигнала, который, как мы увидим, посылает пакет и создает сигнал SIGALRM
один раз в секунду. Обычно обработчик сигналов не запускается напрямую, как у нас, но это можно делать. Обработчик сигналов является обычной функцией языка С, просто в нормальных условиях он асинхронно запускается ядром. Подготовка msghdr для recvmsg
19-24
Мы записываем значения в неизменяемые поля структур msghdr
и iovec
, которые будут передаваться функции recvmsg
. Бесконечный цикл для считывания всех ICMP-сообщений
25-37
Основной цикл программы является бесконечным циклом, считывающим все пакеты, возвращаемые на символьный сокет ICMP. Вызывается функция gettimeofday
для регистрации времени получения пакета, а затем вызывается соответствующая функция протокола ( proc_v4
или proc_v6
) для обработки ICMP-сообщения. В листинге 28.5 приведена функция
tv_sub
, вычисляющая разность двух структур timeval
и сохраняющая результат в первой из них. Листинг 28.5. Функция tv_sub: вычитание двух структур timeval
//lib.tv_sub.c
1 #include "unp.h"
2 void
3 tv_sub(struct timeval *out, struct timeval *in)
4 {
5 if ((out->tv_usec -= in->tv_usec) < 0) { /* out -= in */
6 --out->tv_sec;
7 out->tv_usec += 1000000;
Поделиться:
Популярные книги
Горькие ягодки
Любовные романы:
современные любовные романы
7.44
рейтинг книги
Сама себе хозяйка
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Черный Маг Императора 6
6. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
7.00
рейтинг книги
Последний Паладин. Том 2
2. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Огни Аль-Тура. Завоеванная
4. Эйнар
Любовные романы:
любовно-фантастические романы
эро литература
5.00
рейтинг книги
Законы Рода. Том 7
7. Граф Берестьев
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Жандарм 2
2. Жандарм
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Измена. Мой заклятый дракон
Любовные романы:
любовно-фантастические романы
7.50
рейтинг книги
Его темная целительница
2. Любовь среди туманов
Фантастика:
фэнтези
5.75
рейтинг книги
Кодекс Охотника. Книга V
5. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
4.50
рейтинг книги
Неудержимый. Книга XVI
16. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Жена по ошибке
Любовные романы:
любовно-фантастические романы
7.71
рейтинг книги
Real-Rpg. Город гоблинов
1. Real-Rpg
Фантастика:
фэнтези
7.81
рейтинг книги
Венецианский купец
1. Венецианский купец
Фантастика:
фэнтези
героическая фантастика
альтернативная история
7.31