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

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

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

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



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



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



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



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



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

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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 135 136 137 138 139 140 141 142 143 ... 263

В том случае, когда имеется множество структур адреса сокета, они всегда располагаются в порядке, показанном в таблице.

Пример: получение и вывод записи из таблицы маршрутизации

Теперь мы покажем пример использования маршрутизирующих сокетов. Наша программа получает аргумент командной строки, состоящий из адреса IPv4 в точечно-десятичной записи, и отправляет ядру сообщение RTM_GET для получения этого адреса. Ядро ищет адрес в своей таблице маршрутизации IPv4 и возвращает сообщение RTM_GET с информацией о соответствующей записи из таблицы маршрутизации. Например, если мы выполним на нашем узле freebsd такой код

freebsd # getrt 206.168.112.219

dest: 0.0.0.0

gateway: 12.106.32.1

netmask: 0.0.0.0

мы увидим, что этот адрес получателя использует маршрут по умолчанию (который хранится в таблице маршрутизации с IP-адресом получателя 0.0.0.0 и маской 0.0.0.0). Маршрутизатор следующей ретрансляции — это интернет-шлюз нашей системы. Если мы выполним

freebsd # getrt 192.168.42.0

dest: 192.168.42.0

gateway: AF_LINK, index=2

netmask: 255.255.255.0

задав в качестве получателя главную сеть Ethernet, получателем будет сама сеть. Теперь шлюзом является исходящий интерфейс, возвращаемый в качестве структуры sockaddr_dl с индексом интерфейса 2.

Перед тем как представить исходный код, мы показываем на рис. 18.1, что именно мы пишем в маршрутизирующий сокет и что возвращает ядро.

Рис. 18.1. Обмен данными с ядром на маршрутизирующем сокете для команды RTM_GET

Мы создаем буфер, содержащий структуру rt_msghdr, за которой следует структура адреса сокета, содержащая адрес получателя, информацию о котором должно найти ядро. Тип сообщения (rtm_type) — RTM_GET, а битовая маска (rtm_addrs) — RTA_DST (вспомните табл. 18.2). Эти значения указывают, что структура адреса сокета, следующая за структурой rt_msghdr, — это структура, содержащая адрес получателя. Эта команда может использоваться с любым семейством протоколов (предоставляющим таблицу маршрутизации), поскольку семейство адресов, в которое входит искомый адрес, указано в структуре адреса сокета.

После отправки сообщения ядру мы с помощью функции read читаем ответ, формат которого показан на рис. 18.1 справа: структура rt_msghdr, за которой следует до четырех структур адреса сокета. Какая из четырех структур адреса сокета возвращается, зависит от записи в таблице маршрутизации. Мы сможем идентифицировать возвращаемую структуру адреса сокета по значению элемента rtm_addrs возвращаемой структуры rt_msghdr. Семейство каждой структуры адреса сокета указано в элементе ss_family, и как мы видели в наших предыдущих примерах, первый раз сообщение RST_GET содержало информацию о том, что адрес шлюза является структурой адреса сокета IPv4, а второй раз это была структура адреса сокета канального уровня.

В листинге 18.3 показана первая часть нашей программы.

Листинг 18.3. Первая часть программы, запускающая команду RTM_GET на маршрутизирующем сокете

//route/getrt.c

 1 #include "unproute.h"

 2 #define BUFLEN (sizeof(struct rt_msghdr) + 512)

 3 /* sizeof(struct sockaddr_in6) * 8 = 192 */

 4 #define SEQ 9999

 5 int

 6 main(int argc, char **argv)

 7 {

 8  int sockfd;

 9  char *buf;

10  pid_t pid;

11  ssize_t n;

12  struct rt_msghdr *rtm;

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

14  struct sockaddr_in *sin;

15  if (argc != 2)

16   err_quit("usage: getrt <Ipaddress>");

17  sockfd = Socket(AF_ROUTE, SOCK_RAW, 0); /* необходимы права

                                привилегированного пользователя */

18  buf = Calloc(1, BUFLEN); /* инициализируется нулем */

19  rtm = (struct rt_msghdr*)buf;

20  rtm->rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in);

21  rtm->rtm_version = RTM_VERSION;

22  rtm->rtm_type = RTM_GET;

23  rtm->rtm_addrs = RTA_DST;

24  rtm->rtm_pid = pid = getpid();

25  rtm->rtm_seq = SEQ;

26  sin = (struct sockaddr_in*)(rtm + 1);

27  sin->sin_len = sizeof(struct sockaddr_in);

28  sin->sin_family = AF_INET;

29  Inet_pton(AF_INET, argv[1], &sin->sin_addr);

30  Write(sockfd, rtm, rtm->rtm_msglen);

31  do {

32   n = Read(sockfd, rtm, BUFLEN);

33  } while (rtm->rtm_type != RTM_GET || rtm->rtm_seq != SEQ ||

34   rtm->rtm_pid != pid);

1-3 Наш заголовочный файл unproute.h подключает некоторые необходимые файлы, а затем включает наш файл unp.h. Константа BUFLEN — это размер буфера, который мы размещаем в памяти для хранения нашего сообщения ядру вместе с ответом ядра. Нам необходимо место для одной структуры rt_msghdr и, возможно, восьми структур адреса сокета (максимальное число, которое может возвратиться через маршрутизирующий сокет). Поскольку структура адреса сокета IPv6 имеет размер 28 байт, то значения 512 нам более чем достаточно.

Создание маршрутизирующего сокета

17 Мы создаем символьный сокет в домене AF_ROUTE, что, как мы отмечали ранее, может потребовать прав привилегированного пользователя. Буфер размещается в памяти и инициализируется нулем.

Заполнение структуры rt_msghdr

18-25 Мы заполняем структуру rt_msghdr данными нашего запроса. В этой структуре хранится идентификатор процесса и порядковый номер, который мы выбираем. Мы сравним эти значения, когда будем искать правильный ответ.

Заполнение структуры адреса сокета адресом получателя

26-29 Следом за структурой rt_msghdr мы создаем структуру sockaddr_in, содержащую IPv4-адрес получателя, поиск которого будет проведен ядром в таблице маршрутизации. Все, что мы задаем — это длина адреса, семейство адреса и адрес.

Запись сообщения ядру (функция write) и чтение ответа (функция read)

30-34 Мы передаем сообщение ядру с помощью функции write, и с помощью функции read читаем ответ. Поскольку у других процессов могут быть открытые маршрутизирующие сокеты, а ядро передает копию всех маршрутизирующих сообщений всем маршрутизирующим сокетам, мы должны проверить тип сообщения, порядковый номер и идентификатор процесса, чтобы узнать, что полученное сообщение — это ожидаемое нами сообщение.

Вторая часть этой программы показана в листинге 18.4. Она обрабатывает ответ.

Листинг 18.4. Вторая часть программы, запускающая команду RTM_GET на маршрутизирующем сокете

//route/getrt.c

35  rtm = (struct rt_msghdr*)buf;

36  sa = (struct sockaddr*)(rtm + 1);

37  get_rtaddrs(rtm->rtm_addrs, sa, rti_info);

38  if ((sa = rti_infо[RTAX_DST]) != NULL)

39   printf("dest: %sn", Sock_ntop_host(sa, sa->sa_len));

40  if ((sa = rti_infо[RTAX_GATEWAY]) != NULL)

41   printf("gateway: %sn", Sock_ntop_host(sa, sa->sa_len));

42  if ((sa = rti_info[RTAX_NETMASK]) != NULL)

43   printf("netmask: %sn", Sock_masktop(sa, sa->sa_len));

44  if ((sa = rti_info[RTAX_GENMASK]) != NULL)

45   printf("genmask: %sn", Sock_masktop(sa, sa->sa_len));

46  exit(0);

47 }

34-35 Указатель rtm указывает на структуру rt_msghdr, а указатель sa — на первую следующую за ней структуру адреса сокета.

36 rtm_addrs — это битовая маска той из возможных восьми структур адреса сокета, которая следует за структурой rt_msghdr. Наша функция get_rtaddrs (она показана в следующем листинге), получив эту маску и указатель на первую структуру адреса сокета (sa), заполняет массив rti_info указателями на соответствующие структуры адреса сокета. В предположении, что ядро возвращает все четыре структуры адреса сокета, показанные на рис. 18.1, полученный в результате массив rti_info будет таким, как показано на рис. 18.2.

Рис. 18.2. Структура rti_info, заполненная с помощью нашей функции get_rtaddrs

Затем наша программа проходит массив rti_info, делая все, что ей нужно, с непустыми указателями массива.

37-44 Каждый из присутствующих четырех возможных адресов выводится. Мы вызываем нашу функцию sock_ntop_host для вывода адреса получателя и адреса шлюза, но для вывода двух масок подсети вызываем нашу функцию sock_masktop. Эту новую функцию мы покажем далее.

В листинге 18.5 показана наша функция get_rtaddrs, которую мы вызывали в листинге 18.4.

Листинг 18.5. Создание массива указателей на структуры адреса сокета в маршрутизирующем сообщении

//libroute/get_rtaddrs.c

 1 #include "unproute.h"

 2 /*

 3  * Округляем 'а' до следующего значения, кратного 'size'

 4  */

 5 #define ROUNDUP(a, size) (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))

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

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

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