SOCKET(2) Руководство программиста Linux SOCKET(2)

ИМЯ

socket - создаёт конечную точку соединения

ОБЗОР

#include <sys/types.h> /* смотрите ЗАМЕЧАНИЯ */ #include <sys/socket.h>

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

ОПИСАНИЕ

Системный вызов socket() создаёт конечную точку соединения и возвращает файловый дескриптор, указывающий на эту точку. Возвращаемый при успешном выполнении файловый дескриптор будет иметь самый маленький номер, который не используется процессом.

Параметр domain задает домен соединения: выбирает семейство протоколов, которое будет использоваться для создания соединения. Семейства описаны в <sys/socket.h>. В настоящее время распознаются такие форматы:

Имя Цель Справочная страница
AF_UNIX, AF_LOCAL Локальное соединение unix(7)
AF_INET Протоколы Интернет IPv4 ip(7)
AF_INET6 Протоколы Интернет IPv6 ipv6(7)
AF_IPX Протоколы Novell IPX
AF_NETLINK Устройство для взаимодействия с ядром netlink(7)
AF_X25 Протокол ITU-T X.25/ISO-8208 x25(7)
AF_AX25 Протокол любительского радио AX.25
AF_ATMPVC Доступ к низкоуровневым PVC в ATM
AF_APPLETALK AppleTalk ddp(7)
AF_PACKET Низкоуровневый пакетный интерфейс packet(7)
AF_ALG Интерфейс к ядерному крипто-API
AF_XDP Интерфейс XDP (express data path)

Сокет имеет тип type, задающий семантику соединения. В настоящее время определены следующие типы:

Обеспечивает создание двусторонних, надёжных потоков байтов на основе установления соединения. Может также поддерживаться механизм внепоточных данных.
Поддерживает дейтаграммы (ненадежные сообщения с ограниченной длиной без установки соединения).
Обеспечивает работу последовательного двустороннего канала для передачи дейтаграмм на основе соединений; дейтаграммы имеют постоянный размер; от получателя требуется за один раз прочитать целый пакет.
Обеспечивает прямой доступ к сетевому протоколу.
Обеспечивает надежную доставку дейтаграмм без гарантии, что они будут расположены по порядку.
Устарел и не должен использоваться в новых программах; см. packet(7).

Некоторые типы сокетов могут быть не реализованы во всех семействах протоколов.

Начиная с Linux 2.6.27, аргумент type предназначается для двух вещей: кроме определения типа сокета, для изменения поведения socket() он может содержать побитно сложенные любые следующие значения:

Устанавливает флаг состояния файла O_NONBLOCK для нового открытого файлового дескриптора. Использование данного флага заменяет дополнительные вызовы fcntl(2) для достижения того же результата.
Устанавливает флаг close-on-exec (FD_CLOEXEC) для нового открытого файлового дескриптора. Смотрите описание флага O_CLOEXEC в open(2) для того, чтобы узнать как это может пригодиться.

В protocol задаётся определённый протокол, используемый с сокетом. Обычно, только единственный протокол существует для поддержи определённого типа сокета с заданным семейством протоколов, в этом случае в protocol можно указать 0. Однако, может существовать несколько протоколов, тогда нужно указать один из них. Номер используемого протокола зависит от "домена соединения”, по которому устанавливается соединение; см. protocols(5). Смотрите getprotoent(3), где описано, как соотносить имена протоколов с их номерами.

Сокеты типа SOCK_STREAM являются соединениями полнодуплексных байтовых потоков. Они не сохраняют границы записей. Потоковый сокет должен быть в состоянии соединения перед тем, как из него можно будет отсылать данные или принимать их. Соединение с другим сокетом создается с помощью системного вызова connect(2). После соединения данные можно передавать с помощью системных вызовов read(2) и write(2) или одного из вариантов системных вызовов send(2) и recv(2). Когда сеанс закончен, выполняется команда close(2). Внепоточные данные могут передаваться, как описано в send(2), и приниматься, как описано в recv(2).

Протоколы связи, которые реализуют SOCK_STREAM, следят, чтобы данные не были потеряны или дублированы. Если часть данных, для которых имеется место в буфере протокола, не может быть передана за определённое время, соединение считается разорванным. Когда в сокете включен флаг SO_KEEPALIVE, протокол каким-либо способом проверяет, не отключена ли ещё другая сторона. Если процесс посылает или принимает данные, пользуясь «разорванным» потоком, ему выдаётся сигнал SIGPIPE; это приводит к тому, что процессы, не обрабатывающие этот сигнал, завершаются. Сокеты SOCK_SEQPACKET используют те же самые системные вызовы, что и сокеты SOCK_STREAM. Единственное отличие в том, что вызовы read(2) возвращают только запрошенное количество данных, а остальные данные пришедшего пакета будут отброшены. Границы сообщений во входящих дейтаграммах сохраняются.

Сокеты SOCK_DGRAM и SOCK_RAW позволяют посылать дейтаграммы принимающей стороне, заданной при вызове sendto(2). Дейтаграммы обычно принимаются с помощью вызова recvfrom(2), который возвращает следующую дейтаграмму с соответствующим обратным адресом.

Тип SOCK_PACKET считается устаревшим типом сокета; он позволяет получать необработанные пакеты прямо от драйвера устройства. Используйте вместо него packet(7).

Системный вызов fcntl(2) с аргументом F_SETOWN может использоваться для задания группы процессов, которая будет получать сигнал SIGURG, когда прибывают внепоточные данные, или сигнал SIGPIPE, когда соединение типа SOCK_STREAM неожиданно обрывается. Этот вызов также можно использовать, чтобы задать процесс или группу процессов, которые получают асинхронные уведомления о событиях ввода-вывода с помощью SIGIO. Использование F_SETOWN эквивалентно использованию вызова ioctl(2) с аргументом FIOSETOWN или SIOCSPGRP.

Когда сеть сообщает модулю протокола об ошибке (например, в случае IP, используя ICMP-сообщение), то для сокета устанавливается флаг ожидающей ошибки. Следующая операция этого сокета вернёт код ожидающей ошибки. Некоторые протоколы позволяют организовывать очередь ошибок в сокете для получения подробной информацию об ошибке; смотрите IP_RECVERR в ip(7).

Операции сокетов контролируются их параметрами options. Эти параметры описаны в <sys/socket.h>. Вызовы setsockopt(2) и getsockopt(2) используются, чтобы установить и получить необходимые параметры соответственно.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

В случае успешного выполнения возвращается дескриптор, ссылающийся на сокет. В случае ошибки возвращается -1, а значение errno устанавливается соответствующим образом.

ОШИБКИ

Нет прав на создание сокета указанного типа и/или протокола.
Реализация не поддерживает указанное семейства адресов.
Неизвестный протокол или недоступное семейство протоколов.
Неверные флаги в type.
Было достигнуто ограничение по количеству открытых файловых дескрипторов на процесс.
Достигнуто максимальное количество открытых файлов в системе.
Недостаточно памяти для создания сокета. Сокет не может быть создан, пока не будет освобождено достаточное количество ресурсов.
Тип протокола или указанный протокол не поддерживаются в этом домене.

Другие ошибки могут быть созданы модулями протоколов более низкого уровня.

СООТВЕТСТВИЕ СТАНДАРТАМ

POSIX.1-2001, POSIX.1-2008, 4.4BSD.

Флаги SOCK_NONBLOCK и SOCK_CLOEXEC есть только в Linux.

Вызов socket() появился в 4.2BSD. Обычно он переносим в/из не-BSD систем на уровне сокетов BSD (включая варианты System V).

ЗАМЕЧАНИЯ

В POSIX.1 не требуется включение <sys/types.h>, и этот заголовочный файл не требуется в Linux. Однако, для некоторых старых реализаций (BSD) требует данный файл, и в переносимых приложениях для предосторожности, вероятно, лучше его указать.

Для семейств протоколов в 4.x BSD используются константы PF_UNIX, PF_INET, PF_INET и т. д., тогда как AF_UNIX, AF_INET и т. п. используется для указания семейства адресов. Однако, в справочной странице BSD сказано: «Обычно, семейство протоколов совпадает с семейством адресов» и во всех последующих стандартах используется AF_*.

Тип протокола AF_ALG был добавлен в Linux 2.6.38. Подробности об этом интерфейсе смотрите в HTML-документации ядра на странице https://www.kernel.org/doc/htmldocs/crypto-API/User.html.

Тип протокола AF_XDP был добавлен в Linux 4.18. Дополнительную информацию об этом интерфейсе смотрите в файле исходного кода ядра Documentation/networking/af_xdp.rst.

ПРИМЕР

Пример использования socket() показан в getaddrinfo(3).

СМОТРИТЕ ТАКЖЕ

accept(2), bind(2), close(2), connect(2), fcntl(2), getpeername(2), getsockname(2), getsockopt(2), ioctl(2), listen(2), read(2), recv(2), select(2), send(2), shutdown(2), socketpair(2), write(2), getprotoent(3), ip(7), socket(7), tcp(7), udp(7), unix(7)

“An Introductory 4.3BSD Interprocess Communication Tutorial” and “BSD Interprocess Communication Tutorial”, reprinted in UNIX Programmer's Supplementary Documents Volume 1.

2017-09-15 Linux