-->

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

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

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

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

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

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

Перейти на страницу:
ПРИМЕЧАНИЕ

Вспомните наше обсуждение в конце раздела 22.2. Если узел использует более распространенную модель системы с гибкой привязкой (см. раздел 8.8), IP-адрес получателя может отличаться от IP-адреса принимающего интерфейса. В этом случае мы можем определить только адрес получателя дейтаграммы, который не обязательно должен быть адресом, присвоенным принимающему интерфейсу. Чтобы определить принимающий интерфейс, требуется параметр сокета IP_RECVIF или IPV6_PKTINFO.

В листинге 22.13 показана первая часть примера применения этой технологии к эхо-серверу UDP, который связывается со всеми адресами направленной передачи, широковещательной передачи и, наконец, с универсальными адресами.

Листинг 22.13. Первая часть сервера UDP, который с помощью функции bind связывается со всеми адресами

//advio/udpserv03.c

 1 #include "unpifi.h"

 2 void mydg_echo(int, SA*, socklen_t, SA*);

 3 int

 4 main(int argc, char **argv)

 5 {

 6  int sockfd;

 7  const int on = 1;

 8  pid_t pid;

 9  struct ifi_info *ifi, *ifihead;

10  struct sockaddr_in *sa, cliaddr, wildaddr;

11  for (ifihead = ifi = Get_ifi_info(AF_INET, 1);

12   ifi != NULL; ifi = ifi->ifi_next) {

13   /* связываем направленный адрес */

14   sockfd = Socket(AF_INET, SOCK_DGRAM, 0);

15   Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

16   sa = (struct sockaddr_in*)ifi->ifi_addr;

17   sa->sin_family = AF_INET;

18   sa->sin_port = htons(SERV_PORT);

19   Bind(sockfd, (SA*)sa, sizeof(*sa));

20   printf("bound %sn", Sock_ntop((SA*)sa, sizeof(*sa)));

21   if ((pid = Fork()) == 0) { /* дочерний процесс */

22    mydg_echo(sockfd, (SA*)&cliaddr, sizeof(cliaddr), (SA*)sa);

23    exit(0); /* не выполняется */

24   }

Вызов функции get_ifi_info для получения информации об интерфейсе

11-12
 Функция
get_ifi_info
получает все адреса IPv4, включая дополнительные (псевдонимы), для всех интерфейсов. Затем программа перебирает все структуры
ifi_info
.

Создание сокета UDP и связывание адреса направленной передачи

13-20
 Создается сокет UDP, и с ним связывается адрес направленной передачи. Мы также устанавливаем параметр сокета
SO_REUSEADDR
, поскольку мы связываем один и тот же порт (параметр
SERV_PORT
) для всех IP-адресов.

ПРИМЕЧАНИЕ

Не все реализации требуют, чтобы был установлен этот параметр сокета. Например, Беркли-реализации не требуют этого параметра и позволяют с помощью функции bind связать уже связанный порт, если новый связываемый IP-адрес не является универсальным адресом и отличается от всех IP-адресов, уже связанных с портом. Однако Solaris 2.5 для успешного связывания с одним и тем же портом второго адреса направленной передачи требует установки этого параметра.

Порождение дочернего процесса для данного адреса

21-24
Вызывается функция
fork
, порождающая дочерний процесс. В этом дочернем процессе вызывается функция
mydg_echo
, которая ждет прибытия любой дейтаграммы на сокет и отсылает ее обратно отправителю.

В листинге 22.14 показана следующая часть функции

main
, которая обрабатывает широковещательные адреса.

Листинг 22.14. Вторая часть сервера UDP, который с помощью функции bind связывается со всеми адресами

//advio/udpserv03.c

25   if (ifi->ifi_flags & IFF_BROADCAST) {

26    /* пытаемся связать широковещательный адрес */

27    sockfd = Socket(AF_INET, SOCK_DGRAM, 0);

28    Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

29    sa = (struct sockaddr_in*)ifi->ifi_brdaddr;

30    sa->sin_family = AF_INET;

31    sa->sin_port = htons(SERV_PORT);

32    if (bind(sockfd, (SA*)sa, sizeof(*sa)) < 0) {

33     if (errno == EADDRINUSE) {

34      printf("EADDRINUSE: %sn",

35       Sock_ntop((SA*)sa, sizeof(*sa)));

36      Close(sockfd);

37      continue;

38     } else

39      err_sys("bind error for %s",

40       Sock_ntop((SA*)sa, sizeof(*sa)));

41    }

42    printf("bound %sn", Sock_ntop((SA*)sa, sizeof(*sa)));

43    if ((pid = Fork()) == 0) { /* дочерний процесс */

44     mydg_echo(sockfd, (SA*)&cliaddr, sizeof(cliaddr),

45      (SA*)sa);

46     exit(0); /* не выполняется */

47    }

48   }

49  }

Связывание с широковещательными адресами

25-42
 Если интерфейс поддерживает широковещательную передачу, создается сокет UDP и с ним связывается широковещательный адрес. На этот раз мы позволим функции
bind
завершиться с ошибкой
EADDRINUSE
, поскольку если у интерфейса имеется несколько дополнительных адресов (псевдонимов) в одной подсети, то каждый из различных адресов направленной передачи будет иметь один и тот же широковещательный адрес. Подобный пример приведен после листинга 17.3. В этом сценарии мы предполагаем, что успешно выполнится только первая функция
bind
.

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