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

Интервал:

Закладка:

Сделать

Вернемся к примеру из раздела 17.6 — возвращение всех активных интерфейсов в виде связного списка структур ifi_info(см. листинг 17.2). Программа prifinfoостается без изменений (см. листинг 17.3), но теперь мы покажем версию функции get_ifi_info, использующую функцию sysctlвместо вызова SIOCGIFCONFфункции ioctlв листинге 17.4.

Сначала в листинге 18.8 мы представим функцию net_rt_iflist. Эта функция вызывает функцию sysctlс командой NET_RT_IFLIST, чтобы возвратить список интерфейсов для заданного семейства адресов.

Листинг 18.8. Вызов функции sysctl для возвращения списка интерфейсов

//libroute/net_rt_iflist.c

1 #include "unproute.h"

2 char*

3 net_rt_iflist(int family, int flags, size_t *lenp)

4 {

5 int mib[6];

6 char *buf;

7 mib[0] = CTL_NET;

8 mib[1] = AF_ROUTE;

9 mib[2] = 0;

10 mib[3] = family; /* только адреса этого семейства */

11 mib[4] = NET_RT_IFLIST;

12 mib[5] = flags; /* индекс интерфейса или 0.*/

13 if (sysctl(mib, 6, NULL, lenp, NULL, 0)

14 return (NULL);

15 if ((buf = malloc(*lenp)) == NULL)

16 return (NULL);

17 if (sysctl(mib, 6, buf, lenp, NULL, 0)

18 free(buf);

19 return (NULL);

20 }

21 return (buf);

22 }

7-14 Инициализируется массив mib, как показано в табл. 18.3, для возвращения списка интерфейсов и всех сконфигурированных адресов заданного семейства. Затем функция sysctlвызывается дважды. В первом вызове функции третий аргумент нулевой, в результате чего в переменной, на которую указывает lenp, возвращается размер буфера, требуемый для хранения всей информации об интерфейсе.

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 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

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

Интервал:

Закладка:

Сделать


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

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




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


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


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

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