Provided by: manpages-ru-dev_4.27.0-1_all bug

НАИМЕНОВАНИЕ

       accept, accept4 - принять соединение через сокет

БИБЛИОТЕКА

       Стандартная библиотека языка C (libc, -lc)

ОБЗОР

       #include <sys/socket.h>

       int accept(int sockfd, struct sockaddr *_Nullable restrict addr,
                  socklen_t *_Nullable restrict addrlen);

       #define _GNU_SOURCE             /* Смотрите feature_test_macros(7) */
       #include <sys/socket.h>

       int accept4(int sockfd, struct sockaddr *_Nullable restrict addr,
                  socklen_t *_Nullable restrict addrlen, int flags);

ОПИСАНИЕ

       Системный  вызов  accept()  используется  с  типами  сокетов,  основанными  на  соединении  (SOCK_STREAM,
       SOCK_SEQPACKET).Он  извлекает  первый  запрос  на  соединение  из  очереди   ожидающих   соединений   для
       прослушивающего  сокета, sockfd, создаёт новый подключенный сокет и возвращает новый файловый дескриптор,
       указывающий на сокет. Новый сокет более не находится в слушающем  состоянии.  Исходный  сокет  sockfd  не
       изменяется при этом вызове.

       Аргумент  sockfd  -  сокет,  который  был  создан  с помощью socket(2), привязанный к локальному адресу с
       помощью bind(2) и прослушивающий соединения после listen(2).

       Аргумент addr - указатель на структуру sockaddr. Эта структура заполняется адресом равноправного  сокета,
       который   известен  коммуникационному  уровню.Точный  формат  адреса,  возвращаемого  в  параметре  addr,
       определяется семейством адресов  сокета  (смотрите  socket(2)  и  страницу  руководства  соответствующего
       протокола).  Если addr равен NULL, то ничего не помещается; в этом случае addrlen не используется и также
       должен быть NULL.

       С помощью аргумента addrlen осуществляется возврат результата: вызывающая сторона должна  указать  в  нём
       размер  (в  байтах)  структуры,  на  которую  указывает addr; при возврате он будет содержать фактический
       размер равноправного адреса.

       Возвращаемый адрес урежется, если предоставленный буфер окажется  слишком  маленьким;  в  этом  случае  в
       addrlen будет возвращено значение большее чем было в вызове.

       Если  в  очереди  нет  ожидающих запросов на соединение и сокет не помечен как неблокирующий, то accept()
       заблокирует вызвавшую программу до появления соединения.  Если  сокет  помечен  как  неблокирующий,  а  в
       очереди нет запросов на соединение, то accept() завершится с ошибкой EAGAIN или EWOULDBLOCK.

       Для  того,  чтобы  получать уведомления о входящих соединениях через сокет, можно использовать select(2),
       poll(2) или epoll(7). При попытке нового соединения будет  выдано  сообщение  о  чтении,  после  чего  вы
       сможете  вызвать  accept(),  чтобы  получить сокет для этого соединения. Можно также настроить сокет так,
       чтобы он посылал сигнал SIGIO, когда на нём происходит какая-либо активность; более подробно  смотрите  в
       socket(7).

       Если значение flags равно 0, то вызов accept4() равнозначен accept(). К следующим значениям в flags может
       быть применена операция поразрядного логического ИЛИ для получения различного поведения:

       SOCK_NONBLOCK   Устанавливает  флаг  состояния  файла  O_NONBLOCK для нового открытого файлового описания
                       (смотрите open(2)), на которое ссылается новый файловый дескриптор. Использование данного
                       флага делает ненужными дополнительные вызовы fcntl(2) для достижения того же результата.

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

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

       При  успешном  выполнении  эти  системные  вызовы  возвращают  файловый  дескриптор  для принятого сокета
       (неотрицательное целое число). В случае ошибки возвращается -1, errno,  которое  является  сообщением  об
       ошибке, а значение addrlen не изменяется.

   Обработка ошибок
       В  реализации  Linux accept() (и accept4()) передаёт уже ожидающие сетевые ошибки на новый сокет, как код
       ошибки из вызова accept(). Это поведение отличается от других реализаций BSD-сокетов. Для надёжной работы
       приложения должны отслеживать сетевые ошибки, которые могут появиться при работе  accept() с протоколом и
       обрабатывать их как EAGAIN повторно выполняя вызов. В случае TCP/IP такими  ошибками  являются  ENETDOWN,
       EPROTO, ENOPROTOOPT, EHOSTDOWN, ENONET, EHOSTUNREACH, EOPNOTSUPP и ENETUNREACH.

ОШИБКИ

       EAGAIN или EWOULDBLOCK
              Сокет  помечен  как  неблокирующий  и  нет  ни одного соединения, которое можно было бы принять. В
              POSIX.1-2001 и POSIX.1-2008 допускается в этих случаях возвращение ошибки, но не требуется,  чтобы
              эти  константы  имели  одинаковое  значение,  поэтому  переносимое приложение должно проверять обе
              возможности.

       EBADF  Значение sockfd не является открытым файловым дескриптором.

       ECONNABORTED
              Соединение было прервано.

       EFAULT Аргумент addr не находится в пользовательском пространстве адресов с возможностью записи.

       EINTR  Системный вызов был прерван сигналом,  который  был  перехвачен  до  того,  как  было  установлено
              действительное соединение; смотрите signal(7).

       EINVAL Сокет не слушает соединения или недопустимое значение addrlen (например, отрицательное).

       EINVAL (accept4()) недопустимое значение в flags.

       EMFILE Было достигнуто ограничение по количеству открытых файловых дескрипторов на процесс.

       ENFILE Достигнуто максимальное количество открытых файлов в системе.

       ENOBUFS
       ENOMEM Не  хватает  свободной  памяти.  Это  зачастую означает, что выделение памяти ограничено размерами
              буфера сокетов, а не системной памятью.

       ENOTSOCK
              Файловый дескриптор sockfd указывает не на каталог.

       EOPNOTSUPP
              Указанный сокет не относится к типу SOCK_STREAM.

       EPERM  Правила межсетевого экрана запрещают соединение.

       EPROTO Ошибка протокола.

       Кроме того, могут быть возвращены сетевые ошибки для нового  сокета  и  в  соответствии  с  определениями
       протокола.  Различные  ядра  Linux  могут  возвращать  другие  ошибки,  например, ENOSR, ESOCKTNOSUPPORT,
       EPROTONOSUPPORT, ETIMEDOUT. Значение ошибки ERESTARTSYS можно увидеть при трассировке.

ВЕРСИИ

       В Linux новый сокет,  возвращаемый  accept(),  not   не  наследует  флагов  состояния  файла,  таких  как
       O_NONBLOCK  и  O_ASYNC  из  прослушивающего  сокета.  Это поведение отличается от канонической реализации
       сокетов BSD. Переносимые программы не должны полагаться на наследование флагов  состояния  файла  или  их
       отсутствие, а всегда должны устанавливать на сокете, полученном от accept(), все требуемые флаги.

СТАНДАРТЫ

       accept()
              POSIX.1-2008.

       accept4()
              Linux.

ИСТОРИЯ

       accept()
              POSIX.1-2001, SVr4, 4.4BSD (accept()  впервые появился в BSD 4.2 ).

       accept4()
              Linux 2.6.28, glibc 2.10.

ПРИМЕЧАНИЯ

       После  доставки  SIGIO  не  всегда может быть установлено ожидающее соединение или select(2), poll(2) или
       epoll(7) вернут событие доступности чтения, так как подключение  может  быть  удалено  из-за  асинхронной
       сетевой  ошибкой  или  другой поток был вызван раньше accept(). Если это случилось, то вызов блокируется,
       ожидая прибытия следующего подключения. Чтобы гарантировать, что функция accept() никогда не блокируется,
       для переданного сокета sockfd должен быть установлен флаг O_NONBLOCK (см. socket(7)).

       Для определённых протоколов, которые требуют  явного  подтверждения,  например,  DECnet,  accept()  можно
       рассматривать  просто  как  извлечение  из  очереди  следующего запроса на соединение, не подразумевающее
       подтверждения. Подтверждение, в свою очередь, произойдет при следующем чтении или записи в новом файловом
       дескрипторе, а отказ от соединения может произойти при закрытии нового сокета.  В  настоящее  время,  под
       Linux такую семантику имеет только DECnet.

   Тип socklen_t
       В  первоначальной  реализации сокетов в BSD (и в других системах) третий аргумент accept() объявлялся как
       int *. В стандарте черновика POSIX.1g захотели изменить его на  size_t *.  В  поздних  версиях  стандарта
       POSIX и в glibc 2.x используется socklen_t *.

ПРИМЕРЫ

       См. bind(2).

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

       bind(2), connect(2), listen(2), select(2), socket(2), socket(7)

ПЕРЕВОД

       Русский  перевод  этой страницы руководства разработал(и) Dmitry Bolkhovskikh <d20052005@yandex.ru>, Yuri
       Kozlov <yuray@komyakino.ru>, Aleksandr Felda <isk8da@gmail.com> и Kirill Rekhov <krekhov.dev@gmail.com>

       Этот перевод является свободной программной документацией; он распространяется на условиях  общедоступной
       лицензии  GNU  (GNU  General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или
       более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.

       Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите  об  этом
       разработчику(ам)   по   его(их)  адресу(ам)  электронной  почты  или  по  адресу  списка рассылки русских
       переводчиков.

Справочные страницы Linux 6.9.1                   2 мая 2024 г.                                        accept(2)