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

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

Уважаемые читатели!
Тут можно читать бесплатно UNIX: разработка сетевых приложений - Уильям Стивенс. Жанр: Программное обеспечение. Так же Вы можете читать полную версию (весь текст) онлайн книги без регистрации и SMS на сайте Knigi-online.info (книги онлайн) или прочесть краткое содержание, описание, предисловие (аннотацию) от автора и ознакомиться с отзывами (комментариями) о произведении.
Описание онлайн-книги UNIX: разработка сетевых приложений - Уильям Стивенс:
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.

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



📚 "UNIX: разработка сетевых приложений" - это увлекательное путешествие в мир UNIX и сетевого программирования. В книге автор подробно рассматривает основные принципы разработки сетевых приложений под UNIX, раскрывая множество интересных тем и примеров.



Главный герой книги - опытный разработчик, который стремится углубить свои знания в области сетевого программирования под UNIX. Он исследует различные аспекты работы с сетью, изучает протоколы передачи данных и на практике применяет полученные знания.



👨‍💻 Уильям Стивенс - известный специалист в области компьютерных наук, автор множества книг по сетевому программированию. Его работы пользуются популярностью среди разработчиков и студентов по всему миру.



На сайте knigi-online.info вы можете бесплатно и без регистрации слушать аудиокниги онлайн на русском языке. Здесь собраны бестселлеры и лучшие произведения различных жанров, чтобы каждый мог найти что-то по душе.



🎧 Погрузитесь в увлекательный мир UNIX и сетевого программирования вместе с аудиокнигой "UNIX: разработка сетевых приложений" от Уильяма Стивенса. Развивайте свои навыки, открывайте новые горизонты и наслаждайтесь процессом обучения!

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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 138 139 140 141 142 143 144 145 146 ... 263

15-21 Затем в памяти выделяется место для буфера, и функция sysctl вызывается снова, на этот раз с ненулевым третьим аргументом. При этом переменная, на которую указывает lenp, содержит при завершении функции число, равное количеству информации, хранимой в буфере, и эта переменная размещается в памяти вызывающим процессом. Указатель на буфер также возвращается вызывающему процессу.

ПРИМЕЧАНИЕ

Поскольку размер таблицы маршрутизации или число интерфейсов может изменяться между двумя вызовами функции sysctl, значение, возвращаемое при первом вызове, содержит поправочный множитель 10% [128, с. 639-640].

В листинге 18.9 показана первая половина функции get_ifi_info.

Листинг 18.9. Функция get_ifi_info, первая половина

//route/get_ifi_info.c

 3 struct ifi_info *

 4 get_ifi_info(int family, int doaliases)

 5 {

 6  int flags;

 7  char *buf, *next, *lim;

 8  size_t len;

 9  struct if_msghdr *ifm;

10  struct ifa_msghdr *ifam;

11  struct sockaddr *sa, *rti_info[RTAX_MAX];

12  struct sockaddr_dl *sdl;

13  struct ifi_info *ifi, *ifisave, *ifihead, **ifipnext;

14  buf = Net_rt_iflist(family, 0, &len);

15  ifihead = NULL;

16  ifipnext = &ifihead;

17  lim = buf + len;

18  for (next = buf; next < lim; next += ifm->ifm_msglen) {

19   ifm = (struct if_msghdr*)next;

20   if (ifm->ifm_type = RTM_IFINFO) {

21    if (((flags = ifm->ifm_flags) & IFF_UP) == 0)

22     continue; /* игнорируем, если интерфейс не активен */

23    sa = (struct sockaddr*)(ifm + 1);

24    get_rtaddrs(ifm->ifm_addrs, sa, rti_info);

25    if ((sa = rti_info[RTAX_IFP]) != NULL) {

26     ifi = Calloc(1, sizeof(struct ifi_info));

27     *ifipnext = ifi; /* предыдущий указатель указывал на эту

                           структуру */

28     ifipnext = &ifi->ifi_next; /* указатель на следующую структуру */

29     ifi->ifi_flags = flags;

30     if (sa->sa_family == AF_LINK) {

31      sdl = (struct sockaddr_dl*)sa;

32      ifi->ifi_index = sdl->sdl_index;

33      if (sdl->sdl_nlen > 0)

34       snprintf(ifi->ifi_name, IFI_NAME, "%*s",

35        sdl->sdl_nlen, &sdl->sdl_data[0]);

36      else

37       snprintf(ifi->ifi_name, IFI_NAME, "index %d",

38        sdl->sdl_index);

39      if ((ifi->ifi_hlen = sdl->sdl_alen) > 0)

40       memcpy(ifi->ifi_haddr, LLADDR(sdl),

41      min(IFI_HADDR, sdl->sdl_alen));

42     }

43    }

6-14 Мы объявляем локальные переменные и затем вызываем нашу функцию net_rt_iflist.

17-19 Цикл for — это цикл по всем сообщениям маршрутизации, попадающим в буфер в результате выполнения функции sysctl. Мы предполагаем, что сообщение — это структура if_msghdr, и рассматриваем поле ifm_type (вспомните, что первые три элемента трех структур идентичны, поэтому все равно, какую из трех структур мы используем для просмотра типа элемента).

Проверка, включен ли интерфейс

20-22 Для каждого интерфейса возвращается структура RTM_IFINFO. Если интерфейс не активен, он игнорируется.

Определение, какие структуры адреса сокета присутствуют

23-24 sa указывает на первую структуру адреса сокета, следующую за структурой if_msghdr. Наша функция get_rtaddrs инициализирует массив rti_info в зависимости от того, какие структуры адреса сокета присутствуют.

Обработка имени интерфейса

25-42 Если присутствует структура адреса сокета с именем интерфейса, в памяти размещается структура ifi_info и хранятся флаги интерфейса. Предполагаемым семейством этой структуры адреса сокета является AF_LINK, что означает структуру адреса сокета канального уровня. Если элемент sdl_nlen ненулевой, имя интерфейса копируется в структуру ifi_info. В противном случае в качестве имени хранится строка, содержащая индекс интерфейса. Если элемент sdl_alen ненулевой, аппаратный адрес (например, адрес Ethernet) копируется в структуру ifi_info, а его длина также возвращается как ifi_hlen.

В листинге 18.10 показана вторая часть нашей функции get_ifi_info, которая возвращает IP-адреса для интерфейса.

Листинг 18.10. Функция get_ifi_info, вторая часть

//route/get_ifi_info.c

44   } else if (ifm->ifm_type == RTM_NEWADDR) {

45    if (ifi->ifi_addr) { /* уже имеется IP-адрес для интерфейса */

46     if (doaliases == 0)

47      continue;

48     /* у нас имеется новый IP-адрес для существующего интерфейса */

49     ifisave = ifi;

50     ifi = Calloc(1, sizeof(struct ifi_info));

51     *ifipnext = ifi; /* предыдущий указатель указывал на эту

                           структуру */

52     ifipnext = &ifi->ifi_next; /* указатель на следующую структуру */

53     ifi->ifi_flags = ifi_save->ifi_flags;

54     ifi->ifi_index = ifisave->ifi_index;

55     ifi->ifi_hlen = ifisave->ifi_hlen;

56     memcpy(ifi->ifi_name, ifisave->ifi_name, IFI_NAME);

57     memcpy(ifi->ifi_haddr, ifisave->ifi_haddr, IFI_HADDR);

58    }

59    ifam = (struct ifa_msghdr*)next;

60    sa = (struct sockaddr*)(ifam + 1);

61    get_rtaddrs(ifam->ifam_addrs, sa, rti_info);

62    if ((sa = rti_infо[RTAX_IFA]) != NULL) {

63     ifi->ifi_addr = Calloc(1, sa->sa_len);

64     memcpy(ifi->ifi_addr, sa, sa->sa_len);

65    }

66    if ((flags & IFF_BROADCAST) && (sa = rti_infо[RTAX_BRD]) |= NULL) {

67     ifi->ifi_brdaddr = Calloc(1, sa->sa_len);

68     memcpy(ifi->ifi_brdaddr, sa, sa->sa_len);

69    }

70    if ((flags & IFF_POINTOPOINT) &&

71     (sa = rti_infо[RTAX_BRD]) != NULL) {

72     ifi->ifi_dstaddr = Calloc(1, sa->sa_len);

73     memcpy(ifi->ifi_dstaddr, sa, sa->sa_len);

74    }

75   } else

76    err_quit("unexpected message type %d", ifm->ifm_type);

77  }

78  /* "ifihead" указывает на первую структуру в связном списке */

79  return (ifihead); /* указатель на первую структуру в связном списке */

80 }

Возвращение IP-адресов

44-65 Сообщение RTM_NEWADDR возвращается функцией sysctl для каждого адреса, связанного с интерфейсом: для первичного адреса и для всех альтернативных имен (псевдонимов). Если мы уже заполнили IP-адрес для этого интерфейса, то мы имеем дело с альтернативным именем. Поэтому если вызывающему процессу нужен адрес псевдонима, мы должны выделить память для другой структуры ifi_info, скопировать заполненные поля и затем заполнить возвращенный адрес.

Возвращение широковещательного адреса и адреса получателя

66-75 Если интерфейс поддерживает широковещательную передачу, возвращается широковещательный адрес, а если интерфейс является интерфейсом типа «точка-точка», возвращается адрес получателя.

18.6. Функции имени и индекса интерфейса

Документ RFC 3493 [36] определяет четыре функции, обрабатывающие имена и индексы интерфейсов. Эти четыре функции используются во многих случаях, когда необходимо описать интерфейс. Они были предложены в процессе разработки API IPv6 (главы 21 и 27), однако индексы интерфейсов имеются и в API IPv4 (например, в вызове IP_RECVIF или AF_LINK для маршрутизирующего сокета). Основной принцип, объявляемый в этом документе, состоит в том, что каждый интерфейс имеет уникальное имя и уникальный положительный индекс (нуль в качестве индекса никогда не используется).

#include <net/if.h>

unsigned int if_nametoindex(const char *ifname);

Возвращает: положительный индекс интерфейса в случае успешного выполнения, 0 в случае ошибки

char *if_indextoname(unsigned int ifindex, char *ifname);

Возвращает: указатель на имя интерфейса в случае успешного выполнения, NULL в случае ошибки

struct if_nameindex *if_nameindex(void);

Возвращает: непустой указатель в случае успешного выполнения, NULL в случае ошибки

void if_freenameindex(struct if_nameindex *Iptr);

Функция if_nametoindex возвращает индекс интерфейса, имеющего имя ifname. Функция if_indextoname возвращает указатель на имя интерфейса, если задан его индекс ifindex. Аргумент ifname указывает на буфер размера IFNAMSIZ (определяемый в заголовочном файле <net/if.h> из листинга 17.1), который вызывающий процесс должен выделить для хранения результата, и этот указатель возвращается в случае успешного выполнения функции if_indextoname.

Функция if_nameindex возвращает указатель на массив структур if_nameindex:

struct if_nameindex {

 unsigned int if_index; /* 1, 2. ... */

 char *if_name; /* имя, завершаемое нулем: "le0", ... */

1 ... 138 139 140 141 142 143 144 145 146 ... 263
На этой странице вы можете бесплатно читать книгу UNIX: разработка сетевых приложений - Уильям Стивенс бесплатно.
Похожие на UNIX: разработка сетевых приложений - Уильям Стивенс книги

Оставить комментарий

Рейтинговые книги