-->

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

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

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

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

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

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

Перейти на страницу:

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

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

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

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

freebsd # <b>getrt 206.168.112.219</b>

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 # <b>getrt 192.168.42.0</b>

dest: 192.168.42.0

gateway: AF_LINK, index=2

netmask: 255.255.255.0

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

sockaddr_dl
с индексом интерфейса 2.

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

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

Рис. 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 &quot;unproute.h&quot;

 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(&quot;usage: getrt &lt;Ipaddress&gt;&quot;);

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

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

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

19  rtm = (struct rt_msghdr*)buf;

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

21  rtm-&gt;rtm_version = RTM_VERSION;

22  rtm-&gt;rtm_type = RTM_GET;

23  rtm-&gt;rtm_addrs = RTA_DST;

24  rtm-&gt;rtm_pid = pid = getpid();

25  rtm-&gt;rtm_seq = SEQ;

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

27  sin-&gt;sin_len = sizeof(struct sockaddr_in);

28  sin-&gt;sin_family = AF_INET;

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

30  Write(sockfd, rtm, rtm-&gt;rtm_msglen);

31  do {

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

33  } while (rtm-&gt;rtm_type != RTM_GET || rtm-&gt;rtm_seq != SEQ ||

34   rtm-&gt;rtm_pid != pid);

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

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