Scroll to navigation

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.

ОШИБКИ

Адрес защищён, или пользователь не является суперпользователем.
Указанный адрес уже используется.
(доменные сокеты Интернета) В структуре адреса сокета указан номер порта равный нулю, но при попытке привязаться к эфемеридному порту, было определено, что все номера в диапазоне эфемеридных портов уже используются. Смотрите обсуждение /proc/sys/net/ipv4/ip_local_port_range в ip(7).
Значение sockfd не является правильным файловым дескриптором.
Сокет уже привязан к адресу.
Некорректное значение addrlen, или в addr указан некорректный адрес для этого доменного сокета.
Файловый дескриптор sockfd указывает не на каталог.

Следующие ошибки только для сокетов домена UNIX (AF_UNIX):

Поиск запрещён из-за одного из частей префикса пути (См. также path_resolution(7).)
Запрошен несуществующий интерфейс или запрашиваемый адрес не является локальным.
addr указывает вне адресного пространства, доступного пользователю.
При определении addr превышено количество переходов по символьной ссылке.
Аргумент addr слишком большой.
Компонент из каталожного префикса пути сокета не существует.
Недостаточное количество памяти ядра.
Компонент в префиксе пути не является каталогом.
Попытка создания 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