Уильям Стивенс - UNIX: разработка сетевых приложений
- Название:UNIX: разработка сетевых приложений
- Автор:
- Жанр:
- Издательство:Питер
- Год:2007
- Город:Санкт-Петербург
- ISBN:5-94723-991-4
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Уильям Стивенс - UNIX: разработка сетевых приложений краткое содержание
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
UNIX: разработка сетевых приложений - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
3. Если у сервера есть прослушиваемый сокет IPv6, связанный с адресом IPv6, не являющимся адресом IPv4, преобразованным к виду IPv6, или его сокет связан с универсальным адресом при установленном параметре сокета IPV6_V6ONLY (раздел 7.8), этот сокет может принимать исходящие соединения только от клиентов IPv6.
12.3. Клиент IPv6, сервер IPv4
Теперь мы поменяем протоколы, используемые клиентом и сервером в примере из предыдущего раздела. Сначала рассмотрим TCP-клиент IPv6, запущенный на узле с двойным стеком протоколов.
1. Сервер IPv4 запускается на узле, поддерживающем только IPv4, и создает прослушиваемый сокет IPv4.
2. Запускается клиент IPv6 и вызывает функцию gethostbyname
, запрашивая только адреса IPv6 (запрашивает семейство AF_INET6
и устанавливает флаг AI_V4MAPPED
в структуре hints
). Поскольку у сервера, поддерживающего только IPv4, есть лишь записи типа А, мы видим, согласно табл. 11.3, что клиенту возвращается адрес IPv4, преобразованный к виду IPv6.
3. Клиент IPv6 вызывает функцию connect с адресом IPv4, преобразованным к виду IPv6, в структуре адреса сокета IPv6. Ядро обнаруживает преобразованный адрес и автоматически посылает серверу сегмент SYN IPv4.
4. Сервер отвечает сегментом SYN/ACK IPv4, и устанавливается соединение, по которому происходит обмен дейтаграммами IPv4. Этот сценарий мы схематически изображаем на рис. 12.3.

Рис. 12.3. Обработка клиентских запросов в зависимости от типа адреса и типа сокета
■ Если TCP-клиент IPv4 вызывает функцию connect
, задавая адрес IPv4, или если UDP-клиент IPv4 вызывает функцию sendto
, задавая адрес IPv4, ничего особенного не происходит. На рисунке это изображено двумя стрелками, помеченными «IPv4».
■ Если TCP-клиент IPv6 вызывает функцию connect
, задавая адрес IPv6, или если UDP-клиент IPv6 вызывает функцию sendto
, задавая адрес IPv6, тоже ничего особенного не происходит. На рисунке это показано двумя стрелками, помеченными «IPv6».
■ Если TCP-клиент IPv6 вызывает функцию connect
, задавая адрес IPv4, преобразованный к виду IPv6, или если UDP-клиент вызывает функцию sendto
, задавая адрес IPv4, преобразованный к виду IPv6, ядро обнаруживает сопоставленный адрес и инициирует отправку дейтаграммы IPv4 вместо дейтаграммы IPv6. На рисунке это показано двумя штриховыми стрелками.
■ Клиент IPv4 не может задать адрес IPv6 ни функции connect
, ни функции sendto
, поскольку 16-байтовый адрес IPv6 не соответствует 4-байтовой структуре in_addr
в структуре IPv4 sockaddr_in
. Следовательно, на рисунке нет стрелок от сокетов IPv4 к протоколу IPv6.
В предыдущем разделе (дейтаграмма IPv4, приходящая для сокета сервера IPv6) преобразование полученного адреса IPv4 к виду IPv6 выполняется ядром и результат прозрачно (то есть незаметно для приложения) возвращается приложению функцией accept
или recvfrom
. В этом разделе (если необходимо отправить дейтаграмму IPv4 на сокете IPv6) преобразование адреса IPv4 к виду IPv6 выполняется распознавателем в соответствии с правилами, представленными в табл. 11.3, и затем преобразованный адрес прозрачно передается приложению функцией connect
или sendto
.
Резюме: совместимость IPv4 и IPv6
Таблица 12.2, содержащая сочетания клиентов и серверов, подводит итог обсуждению, проведенному в данном и предыдущем разделах.
Таблица 12.2. Обобщение совместимости клиентов и серверов IPv4 и IPv6
Сервер IPv4, узел только IPv4 (только А) | Сервер IPv4, узел только IPv6 (только AAAA) | Сервер IPv4, узел с двойным стеком (А и AAAA) | Сервер IPv6, узел с двойным стеком (А и AAAA) | |
---|---|---|---|---|
Клиент IPv4, узел только IPv4 | IPv4 | Нет | IPv4 | IPv4 |
Клиент IPv6, узел только IPv6 | Нет | IPv6 | Нет | IPv6 |
Клиент IPv4, узел с двойным стеком | IPv4 | Нет | IPv4 | IPv4 |
Клиент IPv6, узел с двойным стеком | IPv4 | IPv6 | Нет* | IPv6 |
Каждая ячейка этой таблицы содержит поля «IPv4» или «IPv6» с указанием используемого протокола, если данное сочетание работает, либо «нет», если комбинация недопустима. Ячейка в последней строке третьей колонки отмечена звездочкой, поскольку совместимость зависит от адреса, выбранного клиентом. При выборе записи типа AAAA отправка дейтаграммы IPv6 будет невозможна. Но выбор записи типа А, которая возвращается клиенту как адрес IPv4, преобразованный к виду IPv6, приведет к отправке дейтаграммы IPv4. Перебрав все адреса, возвращаемые getaddrinfo
, мы обязательно доберемся до адреса IPv4, преобразованного к виду IPv6, пусть даже и потратив некоторое время на безуспешное ожидание.
Хотя четверть из представленных в таблице сочетаний недопустима, в обозримом будущем большинство реализаций IPv6 будут использоваться на узлах с двойным стеком протоколов и поддерживать не только IPv6. Если мы удалим из таблицы вторую строку и вторую колонку, все записи «Нет» исчезнут и единственной проблемой останется запись, помеченная звездочкой.
12.4. Макроопределения проверки адреса IPv6
Существует небольшой класс приложений IPv6, которые должны знать, с каким собеседником они взаимодействуют (IPv4 или IPv6). Эти приложения должны знать, является ли адрес собеседника адресом IPv4, преобразованным к виду IPv6. Определены двенадцать макросов, проверяющих некоторые свойства адреса Ipv6.
#include
int IN6_IS_ADDR_UNSPECIFIED(const struct in6_addr * aptr );
int IN6_IS_ADDR_LOOPBACK(const struct in6_addr * aptr );
int IN6_IS_ADDR_MULTICAST(const struct in6_addr * aptr );
int IN6_IS_ADDR_LINKLOCAL(const struct in6_addr * aptr );
int IN6_IS_ADDR_SITELOCAL(const struct in6_addr * aptr );
int IN6_IS_ADDR_V4MAPPED(const struct in6_addr * aptr );
int IN6_IS_ADDR_V4COMPAT(const struct in6_addr * aptr );
int IN6_IS_ADDR_MC_NODELOCAL(const struct in6_addr * aptr );
int IN6_IS_ADDR_MC_LINKLOCAL(const struct in6_addr * aptr );
int IN6_IS_ADDR_MC_SITELOCAL(const struct in6_addr * aptr );
int IN6_IS_ADDR_MC_ORGLOCAL(const struct in6_addr * aptr );
int IN6_IS_ADDR_MC_GLOBAL(const struct in6_addr * aptr );
Все возвращают: ненулевое значение, если адрес IPv6 имеет указанный тип, 0 в противном случае
Первые семь макросов проверяют базовый тип адреса IPv6. Мы покажем различные типы адресов в разделе А.5. Последние пять макросов проверяют область действия адреса многоадресной передачи IPv6 (см. раздел 19.2).
Клиент IPv6 может вызвать макрос IN6_IS_ADDR_V4MAPPED
для проверки адреса IPv6, возвращенного распознавателем. Сервер IPv6 может вызвать этот макрос для проверки адреса IPv6, возвращенного функцией accept или recvfrom
.
Как пример приложения, которому нужен этот макрос, можно привести FTP и его команду PORT
. Если мы запустим FTP-клиент, зарегистрируемся на FTP-сервере и выполним команду FTP dir
, FTP-клиент пошлет команду PORT
FTP-серверу через управляющее соединение. Она сообщит серверу IP-адрес и порт клиента, с которым затем сервер создаст соединение. (В главе 27 [111] содержатся подробные сведения о протоколе приложения FTP.) Но FTP-клиент IPv6 должен знать, с каким сервером имеет дело — IPv4 или IPv6, поскольку сервер IPv4 требует команду в формате PORT a1, a2, a3, a4, p1, p2
(где первые четыре числа, каждое от 0 до 255, формируют 4-байтовый адрес IPv4, а два последних — 2-байтовый номер порта), а серверу IPv6 необходима команда EPRT
(RFC 2428 [3]), содержащая семейство адреса, адрес в текстовом формате и порт в текстовом формате. В упражнении 12.1 приводятся примеры использования обеих команд.
Интервал:
Закладка: