UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
В том случае, когда имеется множество структур адреса сокета, они всегда располагаются в порядке, показанном в таблице.
Пример: получение и вывод записи из таблицы маршрутизации
Теперь мы покажем пример использования маршрутизирующих сокетов. Наша программа получает аргумент командной строки, состоящий из адреса IPv4 в точечно-десятичной записи, и отправляет ядру сообщение
RTM_GET
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
Перед тем как представить исходный код, мы показываем на рис. 18.1, что именно мы пишем в маршрутизирующий сокет и что возвращает ядро.
Рис. 18.1. Обмен данными с ядром на маршрутизирующем сокете для команды RTM_GET
Мы создаем буфер, содержащий структуру
rt_msghdr
rtm_type
RTM_GET
rtm_addrs
RTA_DST
rt_msghdr
После отправки сообщения ядру мы с помощью функции
read
rt_msghdr
rtm_addrs
rt_msghdr
ss_family
RST_GET
В листинге 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