- bookworm 4.18.1-1
- bookworm-backports 4.24.0-2~bpo12+1
- testing 4.24.0-2
- unstable 4.24.0-2
bind(2) | System Calls Manual | bind(2) |
ИМЯ¶
bind - привязывает имя к сокету
LIBRARY¶
Standard C library (libc, -lc)
СИНТАКСИС¶
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
ОПИСАНИЕ¶
После создания с помощью socket(2), сокет появляется в адресном пространстве (семействе адресов), но без назначенного адреса. bind() назначает адрес, заданный в addr, сокету, указываемому дескриптором файла sockfd. В аргументе addrlen задаётся размер структуры адреса (в байтах), на которую указывает addr. В силу традиции, эта операция называется «присваивание сокету имени».
Обычно, сокету типа SOCK_STREAM нужно назначить локальный адрес с помощью bind() до того, как он сможет принимать соединения (см. accept(2)).
Правила, используемые при привязке имён, отличаются в разных семействах адресов. Подробности см. в соответствующем справочных страницах в разделе 7. Описание AF_INET находится в ip(7), AF_INET6 в ipv6(7), AF_UNIX в unix(7), AF_APPLETALK в ddp(7), AF_PACKET в packet(7), AF_X25 в x25(7), а AF_NETLINK в netlink(7).
Реальная структура, передаваемая через addr, зависит от семейства адресов. Структура sockaddr определяется так:
struct sockaddr {
sa_family_t sa_family;
char sa_data[14]; }
Единственным смыслом этой структуры является преобразование указателя структуры, передаваемого в addr, чтобы избежать предупреждений компилятора. См. ПРИМЕРЫ ниже.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ¶
On success, zero is returned. On error, -1 is returned, and errno is set to indicate the error.
ОШИБКИ¶
- EACCES
- Адрес защищён, или пользователь не является суперпользователем.
- EADDRINUSE
- Указанный адрес уже используется.
- EADDRINUSE
- (доменные сокеты Интернета) В структуре адреса сокета указан номер порта равный нулю, но при попытке привязаться к эфемеридному порту, было определено, что все номера в диапазоне эфемеридных портов уже используются. Смотрите обсуждение /proc/sys/net/ipv4/ip_local_port_range в ip(7).
- EBADF
- Значение sockfd не является правильным файловым дескриптором.
- EINVAL
- Сокет уже привязан к адресу.
- EINVAL
- Некорректное значение addrlen, или в addr указан некорректный адрес для этого доменного сокета.
- ENOTSOCK
- Файловый дескриптор sockfd указывает не на каталог.
Следующие ошибки только для сокетов домена UNIX (AF_UNIX):
- EACCES
- Поиск запрещён из-за одного из частей префикса пути (См. также path_resolution(7).)
- EADDRNOTAVAIL
- Запрошен несуществующий интерфейс или запрашиваемый адрес не является локальным.
- EFAULT
- addr указывает вне адресного пространства, доступного пользователю.
- ELOOP
- При определении addr превышено количество переходов по символьной ссылке.
- ENAMETOOLONG
- Аргумент addr слишком большой.
- ENOENT
- Компонент из каталожного префикса пути сокета не существует.
- ENOMEM
- Недостаточное количество памяти ядра.
- ENOTDIR
- Компонент в префиксе пути не является каталогом.
- EROFS
- Попытка создания inode сокета на файловой системе, доступной только для чтения.
СТАНДАРТЫ¶
POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD, (bind() впервые появился в 4.2BSD).
ЗАМЕЧАНИЯ¶
Описание типа socklen_t смотрите в accept(2).
ДЕФЕКТЫ¶
Не описываются возможности, связанные с работой прозрачных прокси.
ПРИМЕРЫ¶
Пример использования bind() с сокетами домена Internet можно найти в getaddrinfo(3).
Следующий пример показывает как привязать потоковый сокет к домену UNIX (AF_UNIX) и принимать соединения:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/un.h> #include <unistd.h> #define MY_SOCK_PATH "/somepath" #define LISTEN_BACKLOG 50 #define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0) int main(void) {
int sfd, cfd;
socklen_t peer_addr_size;
struct sockaddr_un my_addr, peer_addr;
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sfd == -1)
handle_error("socket");
memset(&my_addr, 0, sizeof(my_addr));
my_addr.sun_family = AF_UNIX;
strncpy(my_addr.sun_path, MY_SOCK_PATH,
sizeof(my_addr.sun_path) - 1);
if (bind(sfd, (struct sockaddr *) &my_addr,
sizeof(my_addr)) == -1)
handle_error("bind");
if (listen(sfd, LISTEN_BACKLOG) == -1)
handle_error("listen");
/* Теперь мы можем принимать входящие соединения по одному
с помощью accept(2). */
peer_addr_size = sizeof(peer_addr);
cfd = accept(sfd, (struct sockaddr *) &peer_addr,
&peer_addr_size);
if (cfd == -1)
handle_error("accept");
/* Код обработки входящего соединения(й)... */
if (close(sfd) == -1)
handle_error("close");
if (unlink(MY_SOCK_PATH) == -1)
handle_error("unlink"); }
СМ. ТАКЖЕ¶
accept(2), connect(2), getsockname(2), listen(2), socket(2), getaddrinfo(3), getifaddrs(3), ip(7), ipv6(7), path_resolution(7), socket(7), unix(7)
ПЕРЕВОД¶
Русский перевод этой страницы руководства был сделан Artyom Kunyov <artkun@guitarplayer.ru>, Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitriy Ovchinnikov <dmitriyxt5@gmail.com>, Dmitry Bolkhovskikh <d20052005@yandex.ru>, ITriskTI <ITriskTI@gmail.com>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>
Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.
Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.
30 октября 2022 г. | Linux man-pages 6.02 |