Provided by: manpages-ru-dev_4.19.0-7_all bug

ИМЯ

       recv, recvfrom, recvmsg - принимает сообщение из сокета

LIBRARY

       Standard C library (libc, -lc)

СИНТАКСИС

       #include <sys/socket.h>

       ssize_t recv(int sockfd, void buf[.len], size_t len,
                        int flags);
       ssize_t recvfrom(int sockfd, void buf[restrict .len], size_t len,
                        int flags,
                        struct sockaddr *_Nullable restrict src_addr,
                        socklen_t *_Nullable restrict addrlen);
       ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

ОПИСАНИЕ

       Системные  вызовы  recv(),  recvfrom() и recvmsg() используются для получения сообщений из
       сокета. Они могут использоваться для получения данных, независимо  от  того,  является  ли
       сокет ориентированным на соединения или нет. В этой странице сперва описаны общие свойства
       всех трёх системных вызовов, а затем описываются различия между ними.

       Вызов recv() отличается от read(2) только наличием аргумента flags.  Если  значение  flags
       равно нулю, то вызов recv() эквивалентен read(2) (но смотрите ЗАМЕЧАНИЯ). Также, вызов

           recv(sockfd, buf, len, flags);

       эквивалентен

           recvfrom(sockfd, buf, len, flags, NULL, NULL);

       При  успешном выполнении все три вызова возвращают длину сообщения. Если сообщение слишком
       длинное и не поместилось в предоставленный буфер, лишние байты  могут  быть  отброшены,  в
       зависимости от типа сокета, на котором принимаются сообщения.

       If  no  messages  are  available  at  the  socket, the receive calls wait for a message to
       arrive, unless the socket is nonblocking (see fcntl(2)), in which case  the  value  -1  is
       returned and errno is set to EAGAIN or EWOULDBLOCK.  The receive calls normally return any
       data available, up to the requested amount, rather than waiting for receipt  of  the  full
       amount requested.

       Для  определения  появления новых данных в сокете приложение может использовать select(2),
       poll(2) или epoll(7).

   Аргумент флагов
       Аргумент flags формируется с помощью объединения логической операцией ИЛИ одного или более
       следующих значений:

       MSG_CMSG_CLOEXEC (только для recvmsg(); начиная с Linux 2.6.23)
              Установить флаг close-on-exec для файлового дескриптора, полученного через доменный
              файловый дескриптор UNIX, с помощью операции SCM_RIGHTS (описана в  unix(7)).  Этот
              флаг полезен по тем же причинам что и флаг O_CLOEXEC у open(2).

       MSG_DONTWAIT (начиная с Linux 2.2)
              Включить  неблокирующий  режим.  Если  операция  могла  бы  привести  к блокировке,
              возвращается  EAGAIN  или  EWOULDBLOCK.  Такое  поведение  подобно  заданию   флага
              O_NONBLOCKfcntl(2)  операцией  F_SETFL),  но  отличие в том, что MSG_DONTWAIT
              указывается в вызове, а O_NONBLOCK задаётся в описании  открытого  файла  (смотрите
              open(2)),  что влияет на все нити вызывающего процесса, а также на другие процессы,
              у которых есть файловые дескрипторы, ссылающиеся на это описание открытого файла.

       MSG_ERRQUEUE (начиная с Linux 2.2)
              Указание этого флага позволяет  получить  из  очереди  ошибок  сокета  накопившиеся
              ошибки.  Ошибка  передаётся  в  вспомогательном  сообщении  тип которого зависит от
              протокола  (для  IPv4  это  IP_RECVERR).  Вызывающий  должен   предоставить   буфер
              достаточного  размера.  Дополнительная  информация  приведена  в  cmsg(3)  и ip(7).
              Содержимое исходного пакета, который привёл к ошибке,  передаётся  в  виде  обычных
              данных  через  msg_iovec.  Исходный  адрес назначения датаграммы, которая привела к
              ошибке, передаётся через msg_name.

              Ошибка передаётся в виде структуры sock_extended_err:

                  #define SO_EE_ORIGIN_NONE    0
                  #define SO_EE_ORIGIN_LOCAL   1
                  #define SO_EE_ORIGIN_ICMP    2
                  #define SO_EE_ORIGIN_ICMP6   3

                  struct sock_extended_err
                  {
                      uint32_t ee_errno;   /* номер ошибки */
                      uint8_t  ee_origin;  /* источник её происхождения */
                      uint8_t  ee_type;    /* тип */
                      uint8_t  ee_code;    /* код */
                      uint8_t  ee_pad;     /* заполнение для выравнивания */
                      uint32_t ee_info;    /* дополнительная информация */
                      uint32_t ee_data;    /* прочие данные */
                      /* далее могут содержаться ещё данные */
                  };

                  struct sockaddr *SO_EE_OFFENDER(struct sock_extended_err *);

              В ee_errno содержится значение errno для ожидающей ошибки. В  ee_origin  содержится
              источник  происхождения  ошибки. Смысл остальных полей зависит от протокола. Макрос
              SO_EE_OFFENDER возвращает указатель на адрес сетевого объекта, породившего  ошибку.
              Если  этот адрес неизвестен, то поле sa_family структуры sockaddr содержит значение
              AF_UNSPEC, а прочие поля  структуры  sockaddr  не  определены.  Содержимое  пакета,
              вызвавшего ошибку, передаётся в виде обычных данных.

              Для  локальных  ошибок  адрес  не  передаётся  (это  можно  выяснить, проверив поле
              cmsg_len  структуры  cmsghdr).  Для  ошибок   при   приёме   устанавливается   флаг
              MSG_ERRQUEUE  в msghdr. После того, как ошибка передана программе, следующая ошибка
              в очереди ошибок становится ожидающей ошибкой и передается программе при  следующей
              операции на сокете.

       MSG_OOB
              Этот  флаг запрашивает приём внеполосных данных, которые в противном случае не были
              бы получены в обычном потоке данных. Некоторые протоколы помещают данные повышенной
              срочности  в  начало  очереди  с  обычными  данными,  и  поэтому этот флаг не может
              использоваться с такими протоколами.

       MSG_PEEK
              Этот флаг заставляет выбрать данные из начала очереди  приёма,  но  не  удалять  их
              оттуда. Таким образом, последующий вызов вернёт те же самые данные.

       MSG_TRUNC (начиная с Linux 2.2)
              Для   «сырых»   данных   (AF_PACKET),   дейтаграмм   Интернета   (начиная  с  Linux
              2.4.27/2.6.8), netlink (начиная с Linux 2.6.22) и дейтаграмм UNIX (начиная с  Linux
              3.4)  возвращает  реальную длину пакета или дейтаграммы, даже если она была больше,
              чем предоставленный буфер.

              Описание использования с потоковым сокетами Интернета смотрите в tcp(7).

       MSG_WAITALL (начиная с Linux 2.2)
              Этим флагом включается блокирование операции до полной обработки  запроса.  Однако,
              этот  вызов  всё  равно  может  вернуть меньше данных, чем было запрошено, если был
              пойман сигнал, произошла ошибка или разрыв соединения, или  если  начали  поступать
              данные  другого  типа,  не  того,  который  был  сначала.  Этот  флаг  не влияет на
              датаграммные сокеты.

   recvfrom()
       Вызов recvfrom() помещает принятое сообщение в буфер buf. Вызывающий должен указать размер
       буфера в len.

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

       Если  вызывающему  адрес  источника  не  нужен, то значение src_addr и addrlen должно быть
       равно NULL.

   recv()
       Вызов recv(), обычно, используется только на соединённом сокете (смотрите connect(2)).  Он
       идентичен вызову:

           recvfrom(fd, buf, len, flags, NULL, 0);

   recvmsg()
       Для   минимизации  количества  передаваемых  аргументов  в  вызов  recvmsg()  используется
       структура msghdr. Она определена в <sys/socket.h> следующим образом:

           struct msghdr {
               void         *msg_name;       /* необязательный адрес */
               socklen_t     msg_namelen;    /* размер адреса */
               struct iovec *msg_iov;        /* массив приёма/передачи */
               size_t        msg_iovlen;     /* количество элементов в msg_iov */
               void         *msg_control;    /* вспомогательные данные,
                                                см. ниже */
               size_t        msg_controllen; /* размер буфера вспомогательных
                                                данных */
               int           msg_flags;      /* флаги принятого сообщения */
           };

       Поле msg_name указывает на выделенный вызывающим буфер, который используется для  возврата
       адреса  источника,  если сокет не соединён. Вызывающий должен указать в msg_namelen размер
       этого буфера перед вызовом; при успешном выполнении вызова в msg_namelen будет содержаться
       длина  возвращаемого адреса. Если приложению не нужно знать адрес источника, то в msg_name
       можно указать NULL.

       В полях msg_iov и msg_iovlen описываются место приёма/передачи, обсуждаемые в readv(2).

       Поле msg_control длиной msg_controllen указывает на буфер для других сообщений,  связанных
       с управлением протоколом или на буфер для разнообразных вспомогательных данных. При вызове
       recvmsg() в поле msg_controllen должен указываться размер  доступного  буфера,  чей  адрес
       передан  в  msg_control;  при успешном выполнении вызова в этом параметре будет находиться
       длина последовательности контрольных сообщений.

       Сообщения имеют следующий вид:

           struct cmsghdr {
               size_t cmsg_len;    /* счетчик байтов данных с заголовком
                                      (тип — socklen_t в POSIX) */
               int    cmsg_level;  /* начальный протокол */
               int    cmsg_type;   /* тип, зависящий от протокола */
           /* после
              unsigned char cmsg_data[]; */
           };

       К вспомогательным данным нужно  обращаться  только  с  помощью  макросов,  определённых  в
       cmsg(3).

       As  an  example,  Linux  uses  this  ancillary  data mechanism to pass extended errors, IP
       options, or file descriptors over UNIX domain sockets.  For further information on the use
       of ancillary data in various socket domains, see unix(7)  and ip(7).

       При  возврате  из  recvmsg()  устанавливается  значение поля msg_flags в msghdr. Оно может
       содержать несколько флагов:

       MSG_EOR
              означает конец записи: возвращённые данные заканчивают запись (обычно  используется
              вместе с сокетами типа SOCK_SEQPACKET).

       MSG_TRUNC
              означает, что хвостовая часть датаграммы была отброшена, потому что датаграмма была
              больше, чем предоставленный буфер.

       MSG_CTRUNC
              означает, что часть управляющих данных была  отброшена  из-за  недостатка  места  в
              буфере вспомогательных данных.

       MSG_OOB
              возвращается для индикации, что получены курируемые или внеполосные данные.

       MSG_ERRQUEUE
              означает, что были получены не данные, а расширенное сообщение об ошибке из очереди
              ошибок сокета.

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

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

       Когда  ответная сторона потока выполняет корректное отключение (shutdown), то возвращается
       0 (обычный возврат «конец файла»).

       В датаграмных сокетах некоторых доменов (например,  доменах  UNIX  и  Internet)  разрешены
       датаграммы нулевой длины. При получении такой датаграммы возвращается значение 0.

       Также  значение  0  может  возвращаться,  если  запрошенное количество принимаемых байт из
       потокового сокета равно 0.

ОШИБКИ

       Здесь представлено несколько стандартных ошибок,  возвращаемых  с  уровня  сокетов.  Могут
       также  появиться  другие  ошибки, возвращаемые из соответствующих протокольных модулей; их
       описание находится в соответствующих справочных страницах.

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

       EBADF  Аргумент sockfd содержит неверный файловый дескриптор.

       ECONNREFUSED
              Удалённый узел отказался устанавливать сетевое соединение (обычно потому,  что  там
              не работает запрошенная служба).

       EFAULT Указатель на приёмный буфер указывает вне адресного пространства процесса.

       EINTR  Приём  данных  был  прерван  сигналом,  а  данные  ещё  не  были доступны; смотрите
              signal(7).

       EINVAL Передан неверный аргумент.

       ENOMEM Не удалось выделить память для recvmsg().

       ENOTCONN
              Сокет, связанный с протоколом, ориентированным на соединение, не был соединён  (см.
              connect(2) и accept(2)).

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

СТАНДАРТЫ

       POSIX.1-2001, POSIX.1-2008, 4.4BSD (эти интерфейсы впервые появились в 4.2BSD).

       В POSIX.1 описаны только флаги MSG_OOB, MSG_PEEK и MSG_WAITALL.

ЗАМЕЧАНИЯ

       Если  ожидает  дейтаграмма  нулевой  длины, то read(2) и recv() с нулевым аргументом flags
       работают по-разному. В этом  случае  read(2)  ничего  не  делает  (дейтаграмма  продолжает
       ждать), а recv() обрабатывает ожидающую дейтаграмму.

       Тип socklen_t появился из POSIX. Также смотрите accept(2).

       According  to POSIX.1, the msg_controllen field of the msghdr structure should be typed as
       socklen_t, and the msg_iovlen field should be typed as int, but glibc currently types both
       as size_t.

       В  recvmmsg(2)  можно найти информацию о специальном системном вызове Linux, который можно
       использовать для приёма нескольких датаграмм за один вызов.

ПРИМЕРЫ

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

СМ. ТАКЖЕ

       fcntl(2), getsockopt(2), read(2), recvmmsg(2), select(2), shutdown(2), socket(2), cmsg(3),
       sockatmark(3), ip(7), ipv6(7), socket(7), tcp(7), udp(7), unix(7)

ПЕРЕВОД

       Русский  перевод  этой страницы руководства был сделан aereiae <aereiae@gmail.com>, Azamat
       Hackimov <azamat.hackimov@gmail.com>, Dmitriy S. Seregin <dseregin@59.ru>, Katrin Kutepova
       <blackkatelv@gmail.com>,  Lockal <lockalsash@gmail.com>, Yuri Kozlov <yuray@komyakino.ru>,
       Баринов Владимир и Иван Павлов <pavia00@gmail.com>

       Этот  перевод  является  бесплатной  документацией;  прочитайте  Стандартную  общественную
       лицензию GNU версии 3 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ или более позднюю, чтобы
       узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

       Если вы обнаружите ошибки в переводе  этой  страницы  руководства,  пожалуйста,  отправьте
       электронное письмо на ⟨man-pages-ru-talks@lists.sourceforge.net⟩.