Mir-knigi.online
Книги онлайн читать бесплатно!
  • Главная
  • Жанры
  • ТОП книг
  • ТОП авторов
  • Контакты

UNIX: разработка сетевых приложений

Часть 241 из 399 Информация о книге

13   err_quit("usage: ssntp <Ipaddress>");

14  sockfd = Udp_client(argv[1], "ntp", (void**)&mcastsa, &salen);

15  wild = Malloc(salen);

16  memcpy(wild, mcastsa. salen); /* копируем семейство и порт */

17  sock_set_wild(wild, salen);

18  Bind(sockfd, wild, salen); /* связываем сокет с универсальным
[3]

                                  адресом */

19 #ifdef MCAST

20  /* получаем список интерфейсов и обрабатываем каждый интерфейс */

21  for (ifi = Get_ifi_info(mcastsa->sa_family, 1); ifi != NULL;

22   ifi = ifi->ifi_next) {

23   if (ifi->ifi_flags & IFF_MULTICAST) {

24    Mcast_join(sockfd, mcastsa, salen, ifi->ififname, 0);

25    printf("joined %s on %s\n",

26     Sock_ntop(mcastsa, salen), ifi->ifi_name);

27   }

28  }

29 #endif

30  from = Malloc(salen);

31  for (;;) {

32   len = salen;

33   n = Recvfrom(sockfd, buf, sizeof(buf), 0, from, &len);

34   Gettimeofday(&now, NULL);

35   sntp_proc(buf, n, &now);

36  }

37 }

Получение IP-адреса многоадресной передачи

12-14
 При выполнении программы пользователь должен задать в качестве аргумента командной строки адрес многоадресной передачи, к которому он будет присоединяться. В случае IPv4 это будет 224.0.1.1 или имя
ntp.mcast.net
. В случае IPv6 это будет
ff05::101
для области действия NTP, локальной в пределах сайта. Наша функция
udp_client
выделяет в памяти пространство для структуры адреса сокета корректного типа (либо IPv4, либо IPv6) и записывает адрес многоадресной передачи и порт в эту структуру. Если эта программа выполняется на узле, не поддерживающем многоадресную передачу, может быть задан любой IP-адрес, так как в этой структуре задействуются только семейство адресов и порт. Обратите внимание, что наша функция
udp_client
не связывает адрес с сокетом (то есть не вызывает функцию
bind
) — она лишь создает сокет и заполняет структуру адреса сокета.

Связывание универсального адреса с сокетом

15-18
 Мы выделяем в памяти пространство для другой структуры адреса сокета и заполняем ее, копируя структуру, заполненную функцией
udp_client
. При этом задаются семейство адреса и порт. Мы вызываем нашу функцию sock_set_wild, чтобы присвоить IP-адресу универсальный адрес, а затем вызываем функцию bind.

Получение списка интерфейсов

20-22
 Наша функция
get_ifi_info
возвращает информацию обо всех интерфейсах и адресах. Запрашиваемое нами семейство адреса берется из структуры адреса сокета, заполненной функцией
udp_client
на основе аргумента командной строки.

Присоединение к группе

23-27
 Мы вызываем нашу функцию
mcast_join
, чтобы присоединиться к группе, заданной аргументом командной строки для каждого интерфейса, поддерживающего многоадресную передачу. Все эти присоединения происходят на одном сокете, который использует эта программа. Как отмечалось ранее, количество присоединений на одном сокете ограничено константой
IP_MAX_MEMBERSHIPS
(которая обычно имеет значение 20), но лишь немногие многоинтерфейсные узлы используют столько интерфейсов.

Чтение и обработка всех пакетов NTP

30-36
 В памяти размещается другая структура адреса сокета для хранения адреса, возвращаемого функцией
recvfrom
, и программа входит в бесконечный цикл, считывая все пакеты NTP, которые получает узел, и вызывая нашу функцию
sntp_proc
(описывается далее) для обработки пакета. Поскольку сокет был связан с универсальным адресом и присоединение к группе произошло на всех интерфейсах, поддерживающих многоадресную передачу, сокет должен получить любой пакет NTP направленной, широковещательной или многоадресной передачи, получаемый узлом. Перед вызовом функции
sntp_proc
мы вызываем функцию
gettimeofday
, чтобы получить текущее время, потому что функция
sntp_proc
вычисляет разницу между временем пакета и текущим временем.

Наша функция

sntp_proc
, показанная в листинге 21.13, обрабатывает пакет NTP.

Листинг 21.13. Функция sntp_proc: обработка пакета NTР

//ssntp/sntp_proc.c

 1 #include "sntp.h"

 2 void

 3 sntp proc(char *buf, ssize_t n, struct timeval *nowptr)

 4 {

 5  int version, mode;

 6  uint32_t nsec, useci;

 7  double usecf;

 8  struct timeval diff;

 9  struct ntpdata *ntp;

10  if (n < (ssize_t)sizeof(struct ntpdata)) {

11   printf("\npacket too small: %d bytes\n", n);

12   return;

13  }

14  ntp = (struct ntpdata*)buf;

15  version = (ntp->status & VERSION_MASK) >> 3;

16  mode = ntp->status & MODE_MASK;

17  printf("\nv%d, mode %d, strat %d, ", version, mode, ntp->stratum);


Перейти к странице:
Предыдущая страница
Следующая страница
Жанры
  • Военное дело
  • Деловая литература
  • Детективы и триллеры
  • Детские
  • Детские книги
  • Документальная литература
  • Дом и дача
  • Дом и Семья
  • Жанр не определен
  • Зарубежная литература
  • Знания и навыки
  • История
  • Компьютеры и Интернет
  • Легкое чтение
  • Любовные романы
  • Научно-образовательная
  • Образование
  • Поэзия и драматургия
  • Приключения
  • Проза
  • Прочее
  • Психология и мотивация
  • Публицистика и периодические издания
  • Религия и духовность
  • Родителям
  • Серьезное чтение
  • Спорт, здоровье и красота
  • Справочная литература
  • Старинная литература
  • Техника
  • Фантастика и фентези
  • Фольклор
  • Хобби и досуг
  • Юмор
Mir-knigi.online

Бесплатная онлайн библиотека для чтения книг без регистрации с телефона или компьютера. У нас собраны последние новинки, мировые бестселлеры книжного мира.

Контакты
  • [email protected]
Информация
  • Карта сайта
© mir-knigi.online, 2026. | Вход