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

Интервал:

Закладка:

Сделать

Данная программа состоит из двух частей: одна половина читает все, что приходит на символьный сокет, и выводит эхо-ответы ICMP, а другая половина один раз в секунду посылает эхо-запросы ICMP. Вторая половина запускается один раз в секунду сигналом SIGALRM.

В листинге 28.2 приведен заголовочный файл ping.h, подключаемый во всех файлах программы.

Листинг 28.2. Заголовочный файл ping.h

//ping/ping.h

1 #include "unp.h"

2 #include

3 #include

4 #include

5 #define BUFSIZE 1500

6 /* глобальные переменные */

7 char sendbuf[BUFSIZE];

8 int datalen; /* размер данных после заголовка ICMP */

9 char *host;

10 int nsent; /* увеличиваем на 1 для каждого sendto() */

11 pid_t pid; /* наш PID */

12 int sockfd;

13 int verbose;

14 /* прототипы функций */

15 void init_v6(void);

16 void proc_v4(char*, ssize_t, struct msghdr*, struct timeval*);

17 void proc_v6(char*, ssize_t., struct msghdr*, struct timeval*);

18 void send_v4(void);

19 void send_v6(void):

20 void readloop(void);

21 void sig_alrm(int);

22 void tv_sub(struct timeval*, struct timeval*);

23 struct proto {

24 void (*fproc)(char*, ssize_t, struct msghdr*, struct timeval*);

25 void (*fsend)(void);

26 void (*finit)(void);

27 struct sockaddr *sasend; /* структура sockaddr{} для отправки,

полученная от getaddrinfo */

28 struct sockaddr *sarecv; /* sockaddr{} для получения */

29 socklen_t salen; /* длина sockaddr{} */

30 int icmpproto; /* значение IPPROTO_xxx для ICMP */

31 } *pr;

32 #ifdef IPV6

33 #include

34 #include

35 #endif

Подключение заголовочных файлов IPv4 и ICMPv4

1-22 Подключаются основные заголовочные файлы IPv4 и ICMPv4, определяются некоторые глобальные переменные и прототипы функций.

Определение структуры proto

23-31 Для обработки различий между IPv4 и IPv6 используется структура proto. Данная структура содержит два указателя на функции, два указателя на структуры адреса сокета, размер структуры адреса сокета и значение протокола для ICMP. Глобальный указатель prбудет указывать на одну из этих структур, которая будет инициализироваться для IPv4 или IPv6.

Подключение заголовочных файлов IPv6 и ICMPv6

32-35 Подключаются два заголовочных файла, определяющие структуры и константы IPv6 и ICMPv6 (RFC 3542 [114]).

Функция mainприведена в листинге 28.3.

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

//ping/main.c

1 #include "ping.h"

2 struct proto proto_v4 =

3 { proc_v4, send_v4, NULL, NULL, NULL, 0, IPPROTO_ICMP };

4 #ifdef IPV6

5 struct proto proto_v6 =

6 { proc_v6, send_v6, init_v6, NULL, NULL, 0, IPPROTO_ICMPV6 };

7 #endif

8 int datalen = 56; /* размер данных в эхо-запросе ICMP */

9 int

10 main(int argc, char **argv)

11 {

12 int c;

13 struct addrinfo *ai;

14 char *h;

15 opterr = 0; /* отключаем запись сообщений getopt() в stderr */

16 while ((с = getopt(argc, argv, "v")) != -1) {

17 switch (c) {

18 case 'v':

19 verbose++;

20 break;

21 case '?':

22 err_quit("unrecognized option %c", c);

23 }

24 }

25 if (optind != argc-1)

26 err_quit("usage: ping [ -v ] ");

27 host = argv[optind];

28 pid = getpid() & 0xffff; /* поле идентификатора ICMP имеет размер 16 бит */

29 Signal(SIGALRM, sig_alrm);

30 ai = Host_serv(host, NULL, 0, 0);

31 h = Sock_ntop_host(ai->ai_addr, ai->ai_addrlen);

32 printf("PING %s (%s): %d data bytes\n",

33 ai->ai_canonname ? ai->ai_canonname : h, h, datalen);

34 /* инициализация в соответствии с протоколом */

35 if (ai->ai_family == AF_INET) {

36 pr = &proto_v4;

37 #ifdef IPV6

38 } else if (ai->ai_family == AF_INET6) {

39 pr = &proto_v6;

40 if (IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6*)

41 ai->ai_addr)->sin6_addr)))

42 err_quit("cannot ping IPv4-mapped IPv6 address");

43 #endif

44 } else

45 err_quit("unknown address family %d", ai->ai_family);

46 pr->sasend = ai->ai_addr;

47 pr->sarecv = Calloc(1, ai->ai_addrlen);

48 pr->salen = ai->ai_addrlen;

49 readloop();

50 exit(0);

51 }

Определение структуры proto для IPv4 и IPv6

2-7 Определяется структура protoдля IPv4 и IPv6. Указатели структуры адреса сокета инициализируются как нулевые, поскольку еще не известно, какая из версий будет использоваться — IPv4 или IPv6.

Длина дополнительных данных

8 Устанавливается количество дополнительных данных (56 байт), которые будут посылаться с эхо-запросом ICMP. При этом полная IPv4-дейтаграмма будет иметь размер 84 байта (20 байт на IPv4-заголовок и 8 байт на ICMP-заголовок), а IPv6-дейтаграмма будет иметь длину 104 байта. Все данные, посылаемые с эхо- запросом, должны быть возвращены в эхо-ответе. Время отправки эхо-запроса будет сохраняться в первых 8 байтах области данных, а затем, при получении эхо- ответа, будет использоваться для вычисления и вывода времени RTT.

Обработка параметров командной строки

15-24 Единственный параметр командной строки, поддерживаемый в нашей версии, это параметр -v, в результате использования которого большинство ICMP-сообщений будут выводиться на консоль. (Мы не выводим эхо-ответы, принадлежащие другой запущенной копии программы ping.) Для сигнала SIGALRMустанавливается обработчик, и мы увидим, что этот сигнал генерируется один раз в секунду и вызывает отправку эхо-запросов ICMP.

Обработка аргумента, содержащего имя узла

31-48 Строка, содержащая имя узла или IP-адрес, является обязательным аргументом и обрабатывается функцией host_serv. Возвращаемая структура addrinfoсодержит семейство протоколов — либо AF_INET, либо AF_INET6. Глобальный указатель pr устанавливается на требуемую в конкретной ситуации структуру proto. Также с помощью вызова функции IN6_IS_ADDR_V4MAPPEDмы убеждаемся, что адрес IPv6 на самом деле не является адресом IPv4, преобразованным к виду IPv6, поскольку даже если возвращаемый адрес является адресом IPv6, узлу будет отправлен пакет IPv4. (Если такая ситуация возникнет, можно переключиться и использовать IPv4.) Структура адреса сокета, уже размещенная в памяти с помощью функции getaddrinfo, используется для отправки, а другая структура адреса сокета того же размера размещается в памяти для получения.

Обработка ответов осуществляется функцией 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));

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

Интервал:

Закладка:

Сделать


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

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




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


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


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

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