UNIX: разработка сетевых приложений - Уильям Стивенс
0/0

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

Уважаемые читатели!
Тут можно читать бесплатно UNIX: разработка сетевых приложений - Уильям Стивенс. Жанр: Программное обеспечение. Так же Вы можете читать полную версию (весь текст) онлайн книги без регистрации и SMS на сайте Knigi-online.info (книги онлайн) или прочесть краткое содержание, описание, предисловие (аннотацию) от автора и ознакомиться с отзывами (комментариями) о произведении.
Описание онлайн-книги UNIX: разработка сетевых приложений - Уильям Стивенс:
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.

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



📚 "UNIX: разработка сетевых приложений" - это увлекательное путешествие в мир UNIX и сетевого программирования. В книге автор подробно рассматривает основные принципы разработки сетевых приложений под UNIX, раскрывая множество интересных тем и примеров.



Главный герой книги - опытный разработчик, который стремится углубить свои знания в области сетевого программирования под UNIX. Он исследует различные аспекты работы с сетью, изучает протоколы передачи данных и на практике применяет полученные знания.



👨‍💻 Уильям Стивенс - известный специалист в области компьютерных наук, автор множества книг по сетевому программированию. Его работы пользуются популярностью среди разработчиков и студентов по всему миру.



На сайте knigi-online.info вы можете бесплатно и без регистрации слушать аудиокниги онлайн на русском языке. Здесь собраны бестселлеры и лучшие произведения различных жанров, чтобы каждый мог найти что-то по душе.



🎧 Погрузитесь в увлекательный мир UNIX и сетевого программирования вместе с аудиокнигой "UNIX: разработка сетевых приложений" от Уильяма Стивенса. Развивайте свои навыки, открывайте новые горизонты и наслаждайтесь процессом обучения!

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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 160 161 162 163 164 165 166 167 168 ... 263

В этом разделе мы создадим клиент SNTP, который прослушивает широковещательные или групповые сообщения NTP на всех присоединенных сетях, а затем выводит разницу во времени между пакетом NTP и текущим истинным временем узла. Мы не пытаемся изменить это время, поскольку для этого необходимы права привилегированного пользователя.

Файл ntp.h, показанный в листинге 21.11, содержит некоторые из основных определений формата пакета NTP.

Листинг 21.11. Заголовок ntp.h: формат пакета NTP и определения

//ssntp/ntp.h

 1 #define JAN_1970 2208988800UL /* 1970 - 1900 в секундах */

 2 struct l_fixedpt { /* 64-разрядное число с фиксированной точкой */

 3  uint32_t int_part;

 4  uint32_t fraction;

 5 };

 6 struct s_fixedpt { /* 32-разрядное число с фиксированной точкой */

 7  u_short int_part;

 8  u_short fraction;

 9 };

10 struct ntpdata { /* заголовок NTP */

11  u_char status;

12  u_char stratum;

13  u_char ppoll;

14  int    precision:8;

15  struct s_fixedpt distance;

16  struct s_fixedpt dispersion;

17  uint32_t refid;

18  struct l_fixedpt reftime;

19  struct l_fixedpt org;

20  struct 1_fixedpt rec;

21  struct l_fixedpt xmt;

22 };

23 #define VERSION_MASK 0x38

24 #define MODE_MASK 0x07

25 #define MODE CLIENT 3

26 #define MODE_SERVER 4

27 #define MODE_BROADCAST 5

2-22 l_fixedpt задает 64-разрядные числа с фиксированной точкой, используемые NTP для отметок времени, a s_fixedpt — 32-разрядные значения с фиксированной точкой, также используемые NTP. Структура ntpdata представляет 48-байтовый формат пакета NTP.

В листинге 21.12 пpeдcтaвлeнa функция main.

Листинг 21.12. Функция main

//ssntp/main.c

 1 #include "sntp.h"

 2 int

 3 main(int argc, char **argv)

 4 {

 5  int sockfd;

 6  char buf[MAXLINE];

 7  ssize_t n;

 8  socklen_t salen, len;

 9  struct ifi_info *ifi;

10  struct sockaddr *mcastsa, *wild, *from;

11  struct timeval now;

12  if (argc != 2)

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 %sn",

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 bytesn", 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("clientn");

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 usecn", 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 в микросекундах.

1 ... 160 161 162 163 164 165 166 167 168 ... 263
На этой странице вы можете бесплатно читать книгу UNIX: разработка сетевых приложений - Уильям Стивенс бесплатно.
Похожие на UNIX: разработка сетевых приложений - Уильям Стивенс книги

Оставить комментарий

Рейтинговые книги