socket - создаёт
конечную
точку
соединения
Standard C library (
libc,
-lc)
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
Системный
вызов
socket()
создаёт
конечную
точку
соединения
и
возвращает
файловый
дескриптор,
указывающий
на эту
точку.
Возвращаемый
при
успешном
выполнении
файловый
дескриптор
будет
иметь
самый
маленький
номер,
который не
используется
процессом.
Параметр
domain
задает
домен
соединения:
выбирает
семейство
протоколов,
которое
будет
использоваться
для
соединения.
Семейства
описаны в
<sys/socket.h>. В
настоящее
время
ядром Linux
распознаются
следующие
форматы:
Имя |
Цель |
Справочная
страница |
AF_UNIX |
Локальное
соединение |
unix(7) |
AF_LOCAL |
Синоним
AF_UNIX
|
|
AF_INET |
Протоколы
Интернет IPv4 |
ip(7) |
AF_AX25 |
Протокол
любительского
радио AX.25 |
. ax25(4) |
AF_IPX |
Протоколы
Novell IPX |
|
AF_APPLETALK |
AppleTalk |
ddp(7) |
AF_X25 |
Протокол ITU-T
X.25/ISO-8208 |
x25(7) |
AF_INET6 |
Протоколы
Интернет IPv6 |
ipv6(7) |
AF_DECnet |
Протокольные
сокеты DECet |
|
AF_KEY |
Протокол
управления
ключами,
изначально
разрабатывавшийся
для
использования
с IPsec |
|
AF_NETLINK |
Устройство
для
взаимодействия
с ядром |
netlink(7) |
AF_PACKET |
Низкоуровневый
пакетный
интерфейс |
packet(7) |
AF_RDS |
. Протокол
надёжных
датаграмных
сокетов (RDS) |
. . rds(7) rds-rdma(7) |
AF_PPPOX |
Транспортный
слой PPP
общего
назначения
для
настройки
туннелей L2 (L2TP
и PPPoE) |
|
AF_LLC |
. Протокол
управления
логической
связью (IEEE 802.2 LLC) |
|
AF_IB |
.
Собственная
адресация
InfiniBand |
|
AF_MPLS |
.
Многопротокольная
коммутация
по меткам |
|
AF_CAN |
. Протокол
шины сети
транспортных
контроллеров |
|
AF_TIPC |
. Протокол
«кластерных
доменных
сокетов» TIPC |
|
AF_BLUETOOTH |
. Сокетный
протокол Bluetooth
низкого
уровня |
|
AF_ALG |
.
Интерфейс
к ядерному
крипто-API |
|
AF_VSOCK |
. Протокол VSOCK
(изначально
«VMWare VSockets») для
связей
гипервизор-гость |
vsock(7) |
AF_KCM |
. KCM (kernel connection multiplexer) interface |
|
AF_XDP |
.
Интерфейс
XDP (express data path) |
|
Подробнее
об
адресных
семействах,
приведённых
выше, а
также
информацию
о других
адресных
семействах
можно
найти в
address_families(7).
Сокет
имеет тип
type,
задающий
семантику
соединения.
В
настоящее
время
определены
следующие
типы:
- SOCK_STREAM
- Обеспечивает
создание
двусторонних,
надёжных
потоков
байтов на
основе
установления
соединения.
Может
также
поддерживаться
механизм
внепоточных
данных.
- SOCK_DGRAM
- Поддерживает
дейтаграммы
(ненадежные
сообщения
с
ограниченной
длиной без
установки
соединения).
- SOCK_SEQPACKET
- Обеспечивает
работу
последовательного
двустороннего
канала для
передачи
дейтаграмм
на основе
соединений;
дейтаграммы
имеют
постоянный
размер; от
получателя
требуется
за один раз
прочитать
целый
пакет.
- SOCK_RAW
- Обеспечивает
прямой
доступ к
сетевому
протоколу.
- SOCK_RDM
- Обеспечивает
надежную
доставку
дейтаграмм
без
гарантии,
что они
будут
расположены
по
порядку.
- SOCK_PACKET
- Устарел
и не должен
использоваться
в новых
программах;
см. packet(7).
Некоторые
типы
сокетов
могут быть
не
реализованы
во всех
семействах
протоколов.
Начиная с Linux 2.6.27,
аргумент
type
предназначается
для двух
вещей:
кроме
определения
типа
сокета, для
изменения
поведения
socket() он может
содержать
побитно
сложенные
любые
следующие
значения:
- SOCK_NONBLOCK
- Устанавливает
флаг
состояния
файла O_NONBLOCK
для нового
открытого
файлового
описания
(смотрите
open(2)), на
которое
ссылается
новый
файловый
дескриптор.
Использование
данного
флага
делает
ненужными
дополнительные
вызовы fcntl(2)
для
достижения
того же
результата.
- SOCK_CLOEXEC
- Устанавливает
флаг 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)
используются,
чтобы
установить
и получить
необходимые
параметры.
On success, a file descriptor for the new socket is returned. On error, -1 is
returned, and
errno is set to indicate the error.
- EACCES
- Нет прав
на
создание
сокета
указанного
типа и/или
протокола.
- EAFNOSUPPORT
- Реализация
не
поддерживает
указанное
семейства
адресов.
- EINVAL
- Неизвестный
протокол
или
недоступное
семейство
протоколов.
- EINVAL
- Неверные
флаги в type.
- EMFILE
- Было
достигнуто
ограничение
по
количеству
открытых
файловых
дескрипторов
на
процесс.
- ENFILE
- Достигнуто
максимальное
количество
открытых
файлов в
системе.
-
ENOBUFS или ENOMEM
- Недостаточно
памяти для
создания
сокета.
Сокет не
может быть
создан,
пока не
будет
освобождено
достаточное
количество
ресурсов.
- EPROTONOSUPPORT
- Тип
протокола
или
указанный
протокол
не
поддерживаются
в этом
домене.
Другие
ошибки
могут быть
созданы
модулями
протоколов
более
низкого
уровня.
POSIX.1-2001, POSIX.1-2008, 4.4BSD.
Флаги
SOCK_NONBLOCK и
SOCK_CLOEXEC есть
только в Linux.
Вызов
socket()
появился в
4.2BSD. Обычно он
переносим
в/из не-BSD
систем на
уровне
сокетов BSD
(включая
варианты
System V).
Для
семейств
протоколов
в 4.x BSD
используются
константы
PF_UNIX,
PF_INET,
PF_INET и т. д.,
тогда как
AF_UNIX,
AF_INET и т. п.
используется
для
указания
семейства
адресов.
Однако, в
справочной
странице BSD
сказано:
«Обычно,
семейство
протоколов
совпадает
с
семейством
адресов» и
во всех
последующих
стандартах
используется
AF_*.
Пример
использования
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),
address_families(7),
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.
Русский
перевод
этой
страницы
руководства
был сделан
Alexander Golubev <
[email protected]>, Azamat Hackimov
<
[email protected]>, Hotellook, Nikita
<
[email protected]>, Spiros Georgaras <
[email protected]>, Vladislav
<
[email protected]>, Yuri Kozlov <
[email protected]>
и Иван
Павлов <
[email protected]>
Этот
перевод
является
бесплатной
документацией;
прочитайте
Стандартную
общественную
лицензию GNU
версии 3
или более
позднюю,
чтобы
узнать об
условиях
авторского
права. Мы не
несем
НИКАКОЙ
ОТВЕТСТВЕННОСТИ.
Если вы
обнаружите
ошибки в
переводе
этой
страницы
руководства,
пожалуйста,
отправьте
электронное
письмо на
[email protected]