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

Тут можно читать онлайн Уильям Стивенс - UNIX: разработка сетевых приложений - бесплатно ознакомительный отрывок. Жанр: comp-osnet, издательство Питер, год 2007. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    UNIX: разработка сетевых приложений
  • Автор:
  • Жанр:
  • Издательство:
    Питер
  • Год:
    2007
  • Город:
    Санкт-Петербург
  • ISBN:
    5-94723-991-4
  • Рейтинг:
    4.33/5. Голосов: 91
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

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

UNIX: разработка сетевых приложений - описание и краткое содержание, автор Уильям Стивенс, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

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

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

UNIX: разработка сетевых приложений - читать книгу онлайн бесплатно (ознакомительный отрывок), автор Уильям Стивенс
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

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

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);

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 (2 32). Результат больше либо равен 0.0 и меньше 1.0. Мы умножаем это число на 1 000 000 — число микросекунд в секунде, записывая результат в переменную useciкак 32-разрядное целое без знака.

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

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Уильям Стивенс читать все книги автора по порядку

Уильям Стивенс - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




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


Отзывы читателей о книге UNIX: разработка сетевых приложений, автор: Уильям Стивенс. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x