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

Листинг 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);

18  if (mode == MODE_CLIENT) {

19   printf("client\n");

20   return;

21  }

22  nsec = ntohl(ntp->xmt.int_part) - JAN_1970;

23  useci = ntohl(ntp->xmt.fraction); /* 32-разрядная дробь */

24  usecf = useci; /* дробь в double */

25  usecf /= 4294967296.0; /* деление на 2**32 -> [0, 1.0) */

26  useci = usecf * 1000000.0; /* дробь в миллионную часть */

27  diff.tv_sec = nowptr->tv_sec - nsec;

28  if ((diff.tv_usec = nowptr->tv_usec - useci) < 0) {

29   diff.tv_usec += 1000000;

30   diff.tv_sec--;

31  }

32  useci = (diff.tv_sec * 1000000) + diff.tv_usec; /* diff в мс */

33  printf("clock difference = %d usec\n", useci);

34 }

Ратификация пакета

10-21 Сначала мы проверяем размер пакета, затем выводим его версию, режим и слой (stratum) сервера. Если режимом является MODE_CLIENT, пакет является запросом клиента, а не ответом сервера, и мы игнорируем его.

Получение времени передачи из пакета NTP

22-34 В пакете NTP нас интересует поле xmt — отметка времени. Это 64-разрядное значение с фиксированной точкой, определяющее момент отправки пакета сервером. Поскольку отметки времени NTP отсчитывают секунды начиная с 1 января 1900 года, а отметки времени Unix — с 1 января 1970 года, сначала мы вычитаем JAN_1970 (число секунд в 70 годах) из целой части.

Дробная часть — это 32-разрядное целое без знака, которое может принимать значение от 0 до 4 294 967 295 включительно. Оно копируется из 32-разрядного целого (usecf) в переменную с плавающей точкой двойной точности (usecf) и делится на 4 294 967 296 (232). Результат больше либо равен 0.0 и меньше 1.0. Мы умножаем это число на 1 000 000 — число микросекунд в секунде, записывая результат в переменную useci как 32-разрядное целое без знака.

Число микросекунд лежит в интервале от 0 до 999 999 (см. упражнение 21.5). Мы преобразуем значение в микросекунды, поскольку отметка времени Unix, возвращаемая функцией gettimeofday, возвращается как два целых числа: число секунд и число микросекунд, прошедшее с 1 января 1970 года (UTC). Затем мы вычисляем и выводим разницу между истинным временем узла и истинным временем сервера NTP в микросекундах.

Один из факторов, не учитываемых нашей программой, — это задержка в сети между клиентом и сервером. Но мы считаем, что пакеты NTP обычно приходят как широковещательные или многоадресные пакеты в локальной сети, а в этом случае задержка в сети составит всего несколько миллисекунд.

Если мы запустим эту программу на узле macosx с сервером NTP на узле freebsd4, который с помощью многоадресной передачи отправляет пакеты NTP в сеть Ethernet каждые 64 с, то получим следующий результат:

macosx # ssntp 224.0.1.1

joined 224.0.1.1.123 on lo0

joined 224.0.1.1.123 on en1

v4, mode 5, strat 3, clock difference = 661 usec

v4, mode 5, strat 3, clock difference = -1789 usec

v4, mode 5, strat 3, clock difference = -2945 usec

v4, mode 5, strat 3, clock difference = -3689 usec

v4, mode 5, strat 3, clock difference = -5425 usec

Перейти на страницу:

Все книги серии Мастер-класс

Секреты резьбы по дереву
Секреты резьбы по дереву

Изделия из древесины и материалов, имитирующих ее текстуру, привычным образом окружают нас в повседневной жизни, поэтому мы относимся к ней как к чему-то обыденному. Но как только ее коснется умелая рука мастера резьбы по дереву, рождается произведение искусства и раскрываются такие качества древесины, как богатая фактура, разнообразие цветов, особая теплота. Эта книга поможет читателю открыть для себя удивительный мир творчества и познать секреты резьбы по дереву. Автор надеется, что начинающие резчики найдут в ней интересный и полезный материал, который позволит им стать мастерами. В приложении представлены рисунки орнаментов и различных узоров, которые на первых порах можно копировать, а по мере приобретения навыка на их основе разрабатывать свои образцы.

Галина Алексеевна Серикова

Сделай сам / Хобби и ремесла / Руководства / Дом и досуг / Словари и Энциклопедии

Похожие книги