-->

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

На нашем литературном портале можно бесплатно читать книгу UNIX: разработка сетевых приложений, Стивенс Уильям Ричард-- . Жанр: ОС и Сети. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале bazaknig.info.
UNIX: разработка сетевых приложений
Название: UNIX: разработка сетевых приложений
Дата добавления: 16 январь 2020
Количество просмотров: 381
Читать онлайн

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

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

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

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала

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

Чтобы продемонстрировать использование этих параметров, мы создали UDP-клиент и UDP-сервер. Клиент представлен в листинге 27.5. Он принимает маршрут от отправителя в командной строке подобно TCP-клиенту IPv4, представленному в листинге 27.4. Сервер печатает маршрут полученного сообщения и обращает этот маршрут для отправки сообщения в обратном направлении.

Листинг 27.5. UDP-клиент, использующий маршрутизацию от отправителя

 1 #include "unp.h"

 2 int

 3 main(int argc, char **argv)

 4 {

 5  int с, sockfd, len = 0;

 6  u_char *ptr = NULL;

 7  void *rth;

 8  struct addrinfo *ai;

 9  if (argc < 2)

10   err_quit("usage: udpcli01 [ <hostname> ... ] <hostname>");

11  if (argc > 2) {

12   int i;

13   len = Inet6_rth_space(IPV6_RTHDR_TYPE_0, argc-2);

14   ptr = Malloc(len);

15   Inet6_rth_init(ptr, len, IPV6_RTHDR_TYPE_0, argc-2);

16   for (i = 1; i < argc-1; i++) {

17    ai = Host_serv(argv[i], NULL, AF_INET6, 0);

18    Inet6_rth_add(ptr,

19     &((struct sockaddr_in6*)ai->ai_addr)->sin6_addr);

20   }

21  }

22  ai = Host_serv(argv[argc-1], SERV_PORT_STR, AF_INET6, SOCK_DGRAM);

23  sockfd = Socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);

24  if (ptr) {

25   Setsockopt(sockfd, IPPROTO_IPV6, IPV6_RTHDR, ptr, len);

26   free(ptr);

27  }

28  dg_cli(stdin, sockfd, ai->ai_addr, ai->ai_addrlen); /* do it all */

29  exit(0);

30 }

Создание маршрута

11-21
 Если при вызове программы было указано более одного аргумента, все параметры командной строки, за исключением последнего, формируют маршрут от отправителя. Сначала мы определяем, какой объем памяти займет заголовок маршрутизации, при помощи функции
inet6_rth_space
, затем выделяем буфер соответствующего размера вызовом
malloc
. После этого каждый адрес маршрута преобразуется в числовую форму функцией
host_serv
и добавляется к маршруту функцией
inet6_rth_add
. Примерно то же самое выполнял и TCP-клиент IPv4, за тем исключением, что здесь мы используем библиотечные функции, а не свои собственные.

Поиск адресата и создание сокета

22-23
 Мы определяем адрес назначения при помощи
host_serv
и создаем сокет для отправки пакетов.

Установка «закрепленного» параметра IPV6_RTHDR и вызов рабочей функции

24-27
 В разделе 27.7 будет показано, что не обязательно отправлять одни и те же вспомогательные данные с каждым пакетом. Вместо этого можно вызвать
setsockopt
таким образом, что один и тот же заголовок будет добавляться ко всем пакетам в рамках одного сеанса. Этот параметр устанавливается только в том случае, если указатель
ptr
не нулевой, то есть мы уже должны были выделить буфер под заголовок маршрутизации. На последнем этапе мы вызываем рабочую функцию
dg_cli
, которая не меняется с листинга 8.4.

Программа UDP-сервера не изменилась по сравнению с предыдущими примерами. Сервер открывает сокет и вызывает функцию

dg_echo
. В листинге 27.6 представлена функция
dg_echo
, печатающая информацию о маршруте от источника (если таковой был получен) и обращающая этот маршрут для отправки сообщения в обратном направлении.

Листинг 27.6. Функция dg_echo, печатающая маршрут

//ipopts/dgechoprintroute.c

 1 #include "unp.h"

 2 void

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

 4 {

 5  int n;

 6  char mesg[MAXLINE];

 7  int on;

 8  char control[MAXLINE];

 9  struct msghdr msg;

10  struct cmsghdr *cmsg;

11  struct iovec iov[1];

12  on = 1;

13  Setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVRTHDR, &on, sizeof(on));

14  bzero(&msg, sizeof(msg));

15  iov[0].iov_base = mesg;

16  msg.msg_name = pcliaddr;

17  msg.msg_iov = iov;

18  msg.msg_iovlen = 1;

19  msg.msg_control = control;

20  for (;;) {

21   msg.msg_namelen = clilen;

22   msg.msg_controllen = sizeof(control);

23   iov[0].iov_len = MAXLINE;

24   n = Recvmsg(sockfd, &msg, 0);

25   for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;

26    cmsg = CMSG_NXTHDR(&msg, cmsg)) {

27    if (cmsg->cmsg_level == IPPROTO_IPV6 &&

28     cmsg->cmsg_type == IPV6_RTHDR) {

Перейти на страницу:
Комментариев (0)
название