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

Интервал:

Закладка:

Сделать
Инициализация указателей связного списка

29-31 Поскольку мы будем возвращать указатель на начало связного списка структур ifi_info, мы используем две переменные ifiheadи ifipnextдля хранения указателей на список по мере его создания.

Следующая часть нашей функции get_ifi_info, содержащая начало основного цикла, показана в листинге 17.5.

Листинг 17.5. Конфигурация интерфейса процесса

//lib/get_ifi_info.c

34 for (ptr = buf; ptr

35 ifr = (struct ifreq*)ptr;

36 #ifdef HAVE_SOCKADDR_SA_LEN

37 len = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len);

38 #else

39 switch (ifr->ifr_addr.sa_family) {

40 #ifdef IPV6

41 case AF_INET6:

42 len = sizeof(struct sockaddr_in6);

43 break;

44 #endif

45 case AF_INET:

46 default:

47 len = sizeof(struct sockaddr);

48 break;

49 }

50 #endif /* HAVE_SOCKADDR_SA_LEN */

51 ptr += sizeof(ifr->ifr_name) + len; /* для следующей строки */

52 #ifdef HAVE_SOCKADDR_DL_STRUCT

53 /* предполагается, что AF_LINK идет перед AF_INET и AF_INET6 */

54 if (ifr->ifr_addr.sa_family == AF_LINK) {

55 struct sockaddr_dl *sdl = (struct sockaddr_dl*)&ifr->ifr_addr;

56 sdlname = ifr->ifr_name;

57 idx = sdl->sdl_index;

58 haddr = sdl->sdl_data + sdl->sdl_nlen;

59 hlen = sdl->sdl_alen;

60 }

61 #endif

62 if (ifr->ifr_addr.sa_family != family)

63 continue; /* игнорируется, если семейство адреса не то */

64 myflags = 0;

65 if ((cptr = strchr(ifr->ifr_name, ':')) != NULL)

66 *cptr = 0; /* замена двоеточия нулем */

67 if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {

68 if (doaliases == 0)

69 continue; /* этот интерфейс уже обработан */

70 myflags = IFI_ALIAS;

71 }

72 memcpy(lastname, ifr->ifr_name, IFNAMSIZ);

73 ifrcopy = *ifr;

74 Ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);

75 flags = ifrcopy.ifr_flags;

76 if ((flags & IFF_UP) == 0)

77 continue; /* игнорируется, если интерфейс не используется */

Переход к следующей структуре адреса сокета

35-51 При последовательном просмотре всех структур i freq ifrуказывает на текущую структуру, а мы увеличиваем ptrна единицу, чтобы он указывал на следующую. Необходимо предусмотреть особенность более новых систем, предоставляющих поле длины для структур адреса сокета, и вместе с тем учесть, что более старые системы этого поля не предоставляют. Хотя в листинге 17.1 структура адреса сокета, содержащаяся в структуре ifreq, объявляется как общая структура адреса сокета, в новых системах она может относиться к произвольному типу. Действительно, в 4.4BSD структура адреса сокета канального уровня также возвращается для каждого интерфейса [128, с. 118]. Следовательно, если поддерживается элемент длины, то мы должны использовать его значение для переустановки нашего указателя на следующую структуру адреса сокета. В противном случае мы определяем длину, исходя из семейства адресов, используя размер общей структуры адреса сокета (16 байт) в качестве значения по умолчанию.

ПРИМЕЧАНИЕ

В системах, поддерживающих IPv6, не оговаривается, возвращается ли адрес IPv6 вызовом SIOCGIFCONF. Для более новых систем мы вводим оператор case, в котором предусмотрена возможность возвращения адресов IPv6. Проблема состоит в том, что объединение в структуре ifreq определяет возвращаемые адреса как общие 16-байтовые структуры sockaddr, подходящие для 16-байтовых структур sockaddr_in IPv4, но для 24-байтовых структур sockaddr_in6 IPv6 они слишком малы. В случае возвращения адресов IPv6 возможно некорректное поведение существующего кода, созданного в предположении, что в каждой структуре ifreq содержится структура sockaddr фиксированного размера. В системах, где структура sockaddr имеет поле sa_len, никаких проблем не возникает, потому что такие системы легко могут указывать размер структур sockaddr.

52-60 Если система возвращает структуры sockaddrсемейства AF_LINKв SIOCGIFCONF, мы копируем индекс интерфейса и данные об аппаратном адресе из таких структур.

62-63 Мы игнорируем все адреса из семейств, отличных от указанного вызывающим процессом в аргументе функции get_ini_info.

Обработка альтернативных имен

64-72 Нам нужно обнаружить все альтернативные имена (псевдонимы), которые могут существовать для интерфейса, то есть присвоенные этому интерфейсу дополнительные адреса. Обратите внимание в наших примерах, следующих за листингом 17.3, что в Solaris псевдоним содержит двоеточие, в то время как в 4.4BSD имя интерфейса в псевдониме не изменяется. Чтобы обработать оба случая, мы сохраняем последнее имя интерфейса в lastnameи сравниваем его только до двоеточия, если оно присутствует. Если двоеточия нет, мы игнорируем этот интерфейс в том случае, когда имя эквивалентно последнему обработанному интерфейсу.

Получение флагов интерфейса

73-77 Мы выполняем вызов SIOCGIFFLAGSфункции ioctl(см. раздел 16.5), чтобы получить флаги интерфейса. Третий аргумент функции ioctl— это указатель на структуру ifreq, содержащую имя интерфейса, для которого мы хотим получить флаги. Мы создаем копию структуры ifreq, перед тем как запустить функцию ioctl, поскольку в противном случае этот вызов перезаписал бы IP-адрес интерфейса, потому что оба они являются элементами одного и того же объединения из листинга 17.1. Если интерфейс не активен, мы игнорируем его.

В листинге 17.6 представлена третья часть нашей функции.

Листинг 17.6. Получение и возвращение адресов интерфейса

//ioctl/get_ifi_infо.c

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

79 *ifipnext = ifi; /* prev указывает на новую структуру */

80 ifipnext = &ifi->ifi_next; /* сюда указывает указатель на

следующую структуру */

81 ifi->ifi_flags = flags; /* значения IFF_xxx */

82 ifi->ifi_myflags = myflags; /* значения IFI_xxx */

83 #if defined(SIOCGIFMTU) && defined(HAVE_STRUCT_IFREQ_IFR_MTU)

84 Ioctl(sockfd, SIOCGIFMTU, &ifrcopy);

85 ifi->ifi_mtu = ifrcopy.ifr_mtu;

86 #else

87 ifi->ifi_mtu = 0;

88 #endif

89 memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME);

90 ifi->ifi_name[IFI_NAME-1] = '\0';

91 /* если sockaddr_dl относится к другому интерфейсу, он игнорируется */

92 if (sdlname == NULL || strcmp(sdlname, ifr->ifr_name) != 0)

93 idx = hlen = 0;

94 ifi->ifi_index = idx;

95 ifi->ifi_hlen = hlen;

96 if (ifi->ifi_hlen > IFI_HADDR)

97 ifi->ifi_hlen = IFI_HADDR;

98 if (hlen)

99 memcpy(ifi->ifi_haddr, haddr, ifi->ifi_hlen);

Выделение памяти и инициализация структуры ifi_info

78-99На этом этапе мы знаем, что возвратим данный интерфейс вызывающему процессу. Мы выделяем память для нашей структуры ifi_infoи добавляем ее в конец связного списка, который мы создаем. Мы копируем флаги и имя интерфейса в эту структуру. Далее мы проверяем, заканчивается ли имя интерфейса нулем, и поскольку функция callосинициализирует выделенную в памяти область нулями, мы знаем, что ifi_hlenинициализируется нулем, a ifi_next— пустым указателем.

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

Интервал:

Закладка:

Сделать


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

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




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


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


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

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