UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Макрокоманда
SETPASS
SETBLOCK
WILLPASS
WILLBLOCK
В качестве примера рассмотрим приложение, которое будет получать только ICMPv6-извещения маршрутизатора:
struct icmp6_filter myfilt;
fd = Socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
ICMP6_FILTER_SETBLOCKALL(&myfilt);
ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &myfilt);
Setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &myfilt, sizeof(myfilt));
Сначала мы блокируем все типы сообщений (поскольку по умолчанию все типы сообщений пересылаются), а затем разрешаем пересылать только извещения маршрутизатора. Несмотря на то, что мы используем фильтр, приложение должно быть готово к получению всех типов пакетов ICMPv6, потому что любые пакеты ICMPv6, полученные между вызовами
socket
setsockopt
ICMP6_FILTER
28.5. Программа ping
В данном разделе приводится версия программы
ping
ping
ping
ping
Действие программы ping предельно просто: по некоторому IP-адресу посылается эхо-запрос ICMP, и этот узел отвечает эхо-ответом ICMP. Оба эти сообщения поддерживаются в обеих версиях — и в IPv4, и в IPv6. На рис. 28.1 приведен формат ICMP-сообщений.
Рис. 28.1. Формат сообщений эхо-запроса и эхо-ответа ICMPv4 и ICMPv6
В табл. А.5 и А.6 приведены значения поля тип (type) для этих сообщений и говорится, что значение поля код (code) равно нулю. Далее будет показано, что в поле идентификатор (identifier) указывается идентификатор процесса
ping
В листинге 28.1 [1] приведены примеры работы нашей программы. В первом используется версия IPv4, а во втором IPv6. Обратите внимание, что мы установили для нашей программы
ping
Листинг 28.1. Примеры вывода программы ping
freebsd % <b>ping www.google.com</b>
PING www.google.com (216.239.57.99): 56 data bytes
64 bytes from 216.239.57.99: seq=0, ttl=53, rtt=5.611 ms
64 bytes from 216.239.57.99: seq=1, ttl=53, rtt=5.562 ms
64 bytes from 216.239.57 99: seq=2, ttl=53, rtt=5.589 ms
64 bytes from 216.239.57.99: seq=3, ttl=53, rtt=5.910 ms
freebsd % <b>ping www.kame.net</b>
PING orange.kame.net (2001:200:0:4819:203:47ff:fea5:3085): 56 data bytes
64 bytes from 2001:200:0:4819:203:47ff:fea5:3085: seq=0, hlim=52, rtt=422.066 ms
64 bytes from 2001:200:0:4819:203:47ff:fea5:3085: seq=1, hlim=52, rtt=417.398 ms
64 bytes from 2001:200:0:4819:203:47ff:fea5:3085: seq=2, hlim=52, rtt=416.528 ms
64 bytes from 2001:200:0:4819.203.47ff:fea5:3085: seq=3, hlim=52, rtt=429.192 ms
На рис. 28.2 приведен обзор функций, составляющих программу
ping
Рис. 28.2. Обзор функций программы ping
Данная программа состоит из двух частей: одна половина читает все, что приходит на символьный сокет, и выводит эхо-ответы ICMP, а другая половина один раз в секунду посылает эхо-запросы ICMP. Вторая половина запускается один раз в секунду сигналом
SIGALRM
В листинге 28.2 приведен заголовочный файл
ping.h
Листинг 28.2. Заголовочный файл ping.h
//ping/ping.h
1 #include "unp.h"
2 #include <netinet/in_systm.h>
3 #include <netinet/in.h>
4 #include <netinet/ip_icmp.h>
5 #define BUFSIZE 1500
6 /* глобальные переменные */
7 char sendbuf[BUFSIZE];
8 int datalen; /* размер данных после заголовка ICMP */
9 char *host;
10 int nsent; /* увеличиваем на 1 для каждого sendto() */
11 pid_t pid; /* наш PID */
12 int sockfd;
13 int verbose;
14 /* прототипы функций */