Рудофф Эндрю М. - UNIX: разработка сетевых приложений. 3-е изд. стр 34.

Шрифт
Фон

мнение, что это можно было бы разрешить, и тогда возвращаемое значение было бы адресом IPv4, преобразованным к виду IPv6 (см. рис. А.6). Напишите новую функцию inet_pton_loose, реализующую такой сценарий: если используется семейство адресов AF_INETи функция inet_ptonвозвращает нуль, вызовите функцию inet_atonи посмотрите, успешно ли она выполнится. Аналогично, если используется семейство адресов AF_INET6и функция inet_ptonвозвращает нуль, вызовите функцию inet_aton, и если она выполнится успешно, возвратите адрес IPv4, преобразованный к виду IPv6.

Глава 4 Элементарные сокеты TCP

4.1. Введение

Мы также опишем параллельные (concurrent) серверы типичную технологию Unix для обеспечения параллельной обработки множества клиентов одним сервером. Подключение очередного клиента заставляет сервер выполнить функцию fork, порождающую новый серверный процесс для обслуживания этого клиента. Здесь применительно к использованию функции forkмы будем рассматривать модель «каждому клиенту один процесс », а в главе 26 при обсуждении программных потоков расскажем о модели «каждому клиенту один поток ».

На рис. 4.1 представлен типичный сценарий взаимодействия, происходящего между клиентом и сервером. Сначала запускается сервер, затем, спустя некоторое время, запускается клиент, который соединяется с сервером. Предполагается, что клиент посылает серверу запрос, сервер этот запрос обрабатывает и посылает клиенту ответ. Так продолжается, пока клиентская сторона не закроет соединение, посылая при этом серверу признак конца файла. Затем сервер закрывает свой конец соединения и либо завершает работу, либо ждет подключения нового клиента.

Рис. 4.1. Функции сокетов для элементарного клиент-серверного соединения TCP

4.2. Функция socket

#include <sys/socket.h>

int socket(int family , int type , int protocol );

Возвращает: неотрицательный дескриптор, если функция выполнена успешно, -1 в случае ошибки

Константа familyзадает семейство протоколов. Ее возможные значения приведены в табл. 4.1. Часто этот параметр функции socketназывают «областью» или «доменом» ( domain ), а не семейством. Значения константы type(тип) перечислены в табл. 4.2. Аргумент protocolдолжен быть установлен в соответствии с используемым протоколом (табл. 4.3) или должен быть равен нулю для выбора протокола, по умолчанию соответствующего заданному семейству и типу.

Таблица 4.1. Константы протокола (family) для функции socket

Семейство сокетов (family)Описание
AF_INETПротоколы IPv4
AF_INET6Протоколы IPv6
AF_LOCALПротоколы доменных сокетов Unix (см. главу 14)
AF_ROUTEМаршрутизирующие сокеты (см. главу 17)
AF_KEYСокет управления ключами

Таблица 4.2. Тип сокета для функции socket

Тип (type)Описание
SOCK STREAMПотоковый сокет
SOCK_DGRAMСокет дейтаграмм
SOCK_SEQPACKETСокет последовательных пакетов
SOCK_RAWСимвольный (неструктурированный) сокет
Таблица 4.3. Возможные значения параметра protocol

ProtocolЗначение
IPPROTO_TCPТранспортный протокол TCP
IPPROTO_UDPТранспортный протокол UDP
IPPROTO_SCTPТранспортный протокол SCTP

Не все сочетания констант familyи typeдопустимы. В табл. 4.4 показаны допустимые сочетания, а также протокол, соответствующий каждой паре. Клетки таблицы, содержащие «Да», соответствуют допустимым комбинациям, для которых нет удобных сокращений. Пустая клетка означает, что данное сочетание не поддерживается.

Таблица 4.4. Сочетания констант family и type для функции socket

AF_INETAF_INET6AF_LOCALAF_ROUTEAF_KEY
SOCK_STREAMTCP/SCTPTCP/SCTPДа
SOCK_DGRAMUDPUDPДа
SOCK_SEQPACKETSCTPSCTPДа
SOCK RAWIPv4IPv6ДаДа

ПРИМЕЧАНИЕ
В качестве первого аргумента функции socket вы также можете встретить константу PF_xxx. Подробнее об этом мы расскажем в конце данного раздела.

Кроме того, вам может встретиться название AF_UNIX (исторически сложившееся в Unix) вместо AF_LOCAL (название из POSIX), и более подробно мы поговорим об этом в главе 14.

Для аргументов family и type существуют и другие значения. Например, 4.4BSD поддерживает и AF_NS (протоколы Xerox NS, часто называемые XNS), и AF_ISO (протоколы OSI). Но сегодня очень немногие используют какой-либо из этих протоколов. Аналогично, значение type для SOCK_SEQPACKET, сокета последовательных пакетов, реализуется и протоколами Xerox NS, и протоколами OSI. Но протокол TCP является потоковым и поддерживает только сокеты SOCK_STREAM.

Linux поддерживает новый тип сокетов, SOCK_PACKET, предоставляющий доступ к канальному уровню, аналогично BPF и DLPI на рис. 2.1. Об этом более подробно рассказывается в главе 29.

Сокет управления ключами AF_KEY является новшеством. Аналогично тому, как маршрутизирующий сокет (AF_ROUTE) является интерфейсом к таблице маршрутизации ядра, сокет управления ключами это интерфейс к таблице ключей ядра. Подробнее об этом рассказывается в главе 19.

дескриптором сокета socket descriptor

AF_xxx и PF_xxx

семейство адресов address family семейство протоколов protocol family

ПРИМЕЧАНИЕ
Просмотр 137 программ с вызовами функции socket в реализации BSD/OS 2.1 показывает, что в 143 случаях вызова задается значение AF_, и только в 8 случаях значение PF_.

Причина создания аналогичных наборов констант с префиксами AF_ и PF_ восходит к 4.1cBSD [69] и к версии функции socket, предшествующей описываемой нами версии (которая появилась с 4.2BSD). Версия функции socket в 4.1cBSD получала четыре аргумента, одним из которых был указатель на структуру sockproto. Первый элемент этой структуры назывался sp_family, и его значение было одним из значений PF_. Второй элемент, sp_protocol, был номером протокола, аналогично третьему аргументу нынешней функции socket. Единственный способ задать семейство протоколов заключался в том, чтобы задать эту структуру. Следовательно, в этой системе значения PF_ использовались как элементы для задания семейства протоколов в структуре sockproto. Значения AF_ играли роль элементов для задания семейства адресов в структурах адресов сокетов. Структура sockproto еще присутствует в 4.4BSD [128, с. 626-627], но служит только для внутреннего использования ядром. Начальное определение содержало для элемента sp_family комментарий «семейство протоколов», но в исходном коде 4.4BSD он был изменен на «семейство адресов».

Еще большую путаницу в эту ситуацию вносит то, что в Беркли-реализации структура данных ядра, содержащая значение, которое сравнивается с первым аргументом функции socket (элемент dom_family структуры domain [128, с. 187]), сопровождается комментарием, где сказано, что в этой структуре содержится значение AF_. Но некоторые структуры domain внутри ядра инициализированы с помощью константы AF_ [128, с. 192], в то время как другие с помощью PF_ [128, с. 646], [112, с. 229].

Еще одно историческое замечание. Страница руководства по 4.2BSD от июля 1983 года, посвященная функции socket, называет ее первый аргумент af и перечисляет его возможные значения как константы AF_.

Наконец, отметим, что POSIX задает первый аргумент функции socket как значение PF_, а значение AF_ использует для структуры адреса сокета. Но далее в структуре addrinfo определяется только одно значение семейства (см. раздел 11.2), предназначенное для использования либо в вызове функции socket, либо в структуре адреса сокета!

Ваша оценка очень важна

0
Шрифт
Фон

Помогите Вашим друзьям узнать о библиотеке