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

Интервал:

Закладка:

Сделать

50 }

51 #endif

52 #ifdef IP_RECVIF

53 if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF) {

54 struct sockaddr_dl *sdl;

55 sdl = (struct sockaddr_dl*)CMSG_DATA(cmptr);

56 pktp->ipi_ifindex = sdl->sdl_index;

57 continue;

58 }

59 #endif

60 err_quit("unknown ancillary data, len = %d, level = %d, type = %d",

61 cmptr->cmsg_len, cmptr->cmsg_level, cmptr->cmsg_type);

62 }

63 return(n);

64 #endif /* HAVE_MSGHDR_MSG_CONTROL */

65 }

34-37 Если реализация не поддерживает элемента msg_control, мы просто обнуляем возвращаемые флаги и завершаем функцию. Оставшаяся часть функции обрабатывает информацию, содержащуюся в структуре msg_control.

Возвращение при отсутствии управляющей информации

38-41 Мы возвращаем значение msg_flagsи передаем управление вызывающей функции в том случае, если нет никакой управляющей информации, управляющая информация была обрезана или вызывающий процесс не требует возвращения структуры unp_in_pktinfo.

Обработка вспомогательных данных

42-43 Мы обрабатываем произвольное количество объектов вспомогательных данных с помощью макросов CMSG_FIRSTHDRи CMSG_NEXTHDR.

Обработка параметра сокета IP_RECVDSTADDR

47-54 Если в составе управляющей информации был возвращен IP-адрес получателя (см. рис. 14.2), он возвращается вызывающему процессу.

Обработка параметра сокета IP_RECVIF

55-63 Если в составе управляющей информации был возвращен индекс интерфейса, он возвращается вызывающему процессу. На рис. 22.1 показано содержимое возвращенного объекта вспомогательных данных.

Рис 221 Объект вспомогательных данных возвращаемый для параметра IPRECVIF - фото 115

Рис. 22.1. Объект вспомогательных данных, возвращаемый для параметра IP_RECVIF

Вспомните структуру адреса сокета канального уровня (см. листинг 18.1). Данные, возвращаемые в объекте вспомогательных данных, представлены в одной из этих структур, но длины трех элементов являются нулевыми (длина имени, адреса и селектора). Следовательно, нет никакой необходимости указывать эти значения, и таким образом структура имеет размер 8 байт, а не 20, как было в листинге 18.1. Возвращаемая нами информация — это индекс интерфейса.

Пример: вывод IP-адреса получателя и флага обрезки дейтаграммы

Для проверки нашей функции мы изменим функцию dg_echo(см. листинг 8.2) так, чтобы она вызывала функцию recvfrom_flagsвместо функции recvfrom. Новая версия функции dg_echoпоказана в листинге 22.3.

Листинг 22.3. Функция dg_echo, вызывающая нашу функцию recvfrom_flags

//advio/dgechoaddr.c

1 #include "unpifi.h"

2 #undef MAXLINE

3 #define MAXLINE 20 /* устанавливаем новое значение, чтобы

пронаблюдать обрезку дейтаграмм */

4 void

5 dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)

6 {

7 int flags;

8 const int on = 1;

9 socklen_t len;

10 ssize_t n;

11 char mesg[MAXLINE], str[INET6_ADDRSTRLEN], ifname[IFNAMSIZ];

12 struct in_addr in_zero;

13 struct in_pktinfo pktinfo;

14 #ifdef IP_RECVDSTADDR

15 if (setsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on)) < 0)

16 err_ret("setsockopt of IP_RECVDSTADDR");

17 #endif

18 #ifdef IP_RECVIF

19 if (setsockopt(sockfd, IPPROTO_IP, IP_RECVIF, &on, sizeof(on)) < 0)

20 err_ret("setsockopt of IP_RECVIF");

21 #endif

22 bzero(&in_zero, sizeof(struct in_addr)); /* IPv4-адрес, состоящий

из одних нулей */

23 for (;;) {

24 len = clilen;

25 flags = 0;

26 n = Recvfrom_flags(sockfd, mesg, MAXLINE, &flags,

27 pcliaddr, &len, &pktinfo);

28 printf("%d-byte datagram from %s", n, Sock_ntop(pcliaddr, len));

29 if (memcmp(&pktinfo.ipi_addr, &in_zero, sizeof(in_zero)) != 0)

30 printf(", to %s", Inet_ntop(AF_INET, &pktinfo.ipi_addr,

31 str, sizeof(str)));

32 if (pktinfo.ipi_ifindex > 0)

33 printf(", recv i/f = %s",

34 If_indextoname(pktinfо.ipi_ifindex, ifname));

35 #ifdef MSG_TRUNC

36 if (flags & MSG_TRUNC)

37 printf(" (datagram truncated)");

38 #endif

39 #ifdef MSG_CTRUNC

40 if (flags & MSG_CTRUNC)

41 printf(" (control info truncated)");

42 #endif

43 #ifdef MSG_BCAST

44 if (flags & MSG_BCAST)

45 printf(" (broadcast)");

46 #endif

47 #ifdef MSG_MCAST

48 if (flags & MSG_MCAST)

49 printf(" (multicast)");

50 #endif

51 printf("\n");

52 Sendto(sockfd, mesg, n, 0, pcliaddr, len);

53 }

54 }

Изменение MAXLINE

2-3 Мы удаляем существующее определение MAXLINE, имеющееся в нашем заголовочном файле unp.h, и задаем новое значение — 20. Это позволит нам увидеть, что произойдет, когда мы получим дейтаграмму UDP, превосходящую размер буфера, переданного функции (в данном случае функции recvmsg).

Установка параметров сокета IP_RECVDSTADDR и IP_RECVIF

14-21 Если параметр сокета IP_RECVDSTADDRопределен, мы включаем его. Аналогично включается параметр сокета IP_RECVIF.

Чтение дейтаграммы, вывод IP-адреса отправителя и порта

24-28 Дейтаграмма читается с помощью вызова функции recvfrom_flags. IP-адрес отправителя и порт ответа сервера преобразуются в формат представления функцией sock_ntop.

Вывод IP-адреса получателя

29-31 Если возвращаемый IP-адрес ненулевой, он преобразуется в формат представления функцией inet_ntopи выводится.

Вывод имени интерфейса, на котором была получена дейтаграмма

32-34 Если индекс интерфейса ненулевой, его имя будет возвращено функцией if_indextoname. Это имя наша функция печатает на экране.

Проверка различных флагов

35-51 Мы проверяем четыре дополнительных флага и выводим сообщение, если какие-либо из них установлены.

22.3. Обрезанные дейтаграммы

В системах, происходящих от BSD, при получении UDP-дейтаграммы, размер которой больше буфера приложения, функция recvmsg устанавливает флаг MSG_TRUNCв элементе msg_flagsструктуры msghdr(см. табл. 14.2). Все Беркли-реализации, поддерживающие структуру msghdrс элементом msg_flags, обеспечивают это уведомление.

ПРИМЕЧАНИЕ

Это пример флага, который должен быть возвращен процессу ядром. В разделе 14.3 мы упомянули о проблеме разработки функций recv и recvfrom: их аргумент flags является целым числом, что позволяет передавать флаги от процесса к ядру, но не наоборот.

К сожалению, не все реализации подобным образом обрабатывают ситуацию, когда размер дейтаграммы UDP оказывается больше, чем предполагалось. Возможны три сценария:

1. Лишние байты игнорируются, и приложение получает флаг MSG_TRUNC, что требует вызова функции recvmsg.

2. Игнорирование лишних байтов без уведомления приложения.

3. Сохранение лишних байтов и возвращение их в последующих операциях чтения на сокете.

ПРИМЕЧАНИЕ

POSIX задает первый тип поведения: игнорирование лишних байтов и установку флага MSG_TRUNC. Ранние реализации SVR4 действуют по третьему сценарию.

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

Интервал:

Закладка:

Сделать


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

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




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


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


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

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