В табл. 15.1 приведены имена доменов.
Таблица 15.1
Домен Описание AF_UNIX Внутренние для UNIX (сокеты файловой системы) AF_INET Интернет-протоколы ARPA (Advanced Research Projects Agency, управление перспективных исследований и разработок) (сокеты сети UNIX) AF_ISO Протоколы стандарта ISO (International Standards Organization, Международная организация по стандартизации) AF_NS Протоколы сетевых систем Xerox AF_IPX Novell-протокол IPX AF_APPLETALK Appletalk DDS (Appletalk Digital Data Service)
К наиболее популярным доменам сокетов относятся AF_UNIX, применяемый для локальных сокетов, реализуемых средствами файловых систем UNIX и Linux, и AF_INET, используемый для сетевых сокетов UNIX. Сокеты домена AF_INET могут применяться программами, взаимодействующими в сетях на базе протоколов TCP/IP, включая Интернет. Интерфейс ОС Windows Winsock также предоставляет доступ к этому домену сокетов.
Параметр сокета type задает характеристики обмена данными, применяемые для нового сокета. Возможными значениями могут быть SOCK_STREAM и SOCK_DGRAM.
□ SOCK_STREAM — это упорядоченный, надежный, основанный на соединении, двунаправленный поток байтов. В случае домена сокетов AF_INET этот тип обмена данными по умолчанию обеспечивается TCP-соединением, которое устанавливается между двумя конечными точками потоковых сокетов при подключении. Данные могут передаваться в двух направлениях по линии связи сокетов. Протоколы TCP включают в себя средства фрагментации и последующей повторной сборки сообщений больших объемов и повторной передачи любых их частей, которые могли быть потеряны в сети.
□ SOCK_DGRAM — дейтаграммный сервис. Вы можете использовать такой сокет для отправки сообщений с фиксированным (обычно небольшим) максимальным объемом, но при этом нет гарантии, что сообщение будет доставлено или что сообщения не будут переупорядочены в сети. В случае сокетов домена AF_INET этот тип передачи данных обеспечивается дейтаграммами UDP (User Datagram Protocol, пользовательский протокол дейтаграмм).
Протокол, применяемый для обмена данными, обычно определяется типом сокета и доменом. Как правило, выбора нет. Параметр protocol применяется в тех случаях, когда выбор все же предоставляется. Задание 0 позволяет выбрать стандартный протокол, используемый во всех примерах данной главы.
Системный вызов socket возвращает дескриптор, во многом похожий на низкоуровневый файловый дескриптор. Когда сокет подключен к концевой точке другого сокета, для отправки и получения данных с помощью сокетов можно применять системные вызовы read и write с дескриптором сокета. Системный вызов close используется для удаления сокетного соединения.
Адреса сокетов
Каждый домен сокетов требует своего формата адресов. В домене AF_UNIX адрес описывается структурой sockaddr_un, объявленной в заголовочном файле sys/un.h:
<b>struct sockaddr_un {</b>
<b> sa_family_t sun_family; /* AF_UNIX */</b>
<b> char sun_path[]; /* Путь к файлу */</b>
<b>};</b>
Для того чтобы адреса разных типов могли передаваться в системные вызовы для обработки сокетов, все адресные форматы описываются похожей структурой, которая начинается с поля (в данном случае sun_family), задающего тип адреса (домен сокета). В домене AF_UNIX адрес задается именем файла в поле структуры sun_path.
В современных системах Linux тип sa_family_t, описанный в стандарте X/Open как объявляемый в заголовочном файле sys/un.h, интерпретируется как тип short. Кроме того, размер pathname, задаваемого в поле sun_path, ограничен (в Linux указывается 108 символов; в других системах может применяться именованная константа, например, UNIX_MAX_PATH). Поскольку размер адресной структуры может меняться, многие системные вызовы сокетов требуют или предоставляют на выходе длину, которая будет использоваться для копирования конкретной адресной структуры.
В домене AF_INET адрес задается с помощью структуры с именем sockaddr_in, определенной в файле netinet/in.h, которая содержит как минимум следующие элементы:
<b>struct sockaddr_in {</b>
<b> short int sin_family; /* AF_INET */</b>
<b> unsigned short int sin_port; /* Номер порта */</b>
<b> struct in_addr sin_addr; /* Интернет-адрес */</b>
<b>};</b>
Структура IP-адреса типа in_addr определена следующим образом:
<b>struct in_addr {</b>
<b> unsigned long int s_addr;</b>
<b>};</b>
Четыре байта IP-адреса образуют одно 32-разрядное значение. Сокет домена AF_INET полностью описывается IP-адресом и номером порта. С точки зрения приложения все сокеты действуют как файловые дескрипторы, и их адреса задаются уникальными целочисленными значениями.
Именование сокета
Для того чтобы сделать сокет (созданный с помощью вызова socket) доступным для других процессов, серверная программа должна присвоить сокету имя. Сокеты домена AF_UNIX связаны с полным именем файла в файловой системе, как вы видели в программе-примере server1. Сокеты домена AF_INET связаны с номером IP-порта.
<b>#include <sys/socket.h></b>
<b>int bind(int socket, const struct sockaddr *address, size_t address len);</b>
Системный вызов bind присваивает адрес, заданный в параметре address, неименованному сокету, связанному с дескриптором сокета socket. Длина адресной структуры передается в параметре address_len: