Provided by: manpages-ru_0.98-4_all bug

НАЗВАНИЕ

       recv, recvfrom, recvmsg - получить сообщение из сокета

КРАТКАЯ СВОДКА

       #include <sys/types.h>
       #include <sys/socket.h>

       int recv(int s, void *buf, size_t len, int flags);

       int  recvfrom(int  s, void *buf, size_t len, int flags, struct sockaddr
       *from, socklen_t *fromlen);

       int recvmsg(int s, struct msghdr *msg, int flags);

ОПИСАНИЕ

       Системные  вызовы  recvfrom  и  recvmsg  используются   для   получения
       сообщений  из  сокета,  и  могут  использоваться  для получения данных,
       независимо от того, является ли сокет ориентированным на соединения или
       нет.

       Если  параметр  from не равен NULL, а сокет не является ориентированным
       на  соединения,  то  адрес  отправителя  в  сообщении  не  заполняется.
       Аргумент  fromlen  передается  по  ссылке,  в  начале  инициализируется
       размером буфера, связанного с from, а при возврате из функции  содержит
       действительный размер адреса.

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

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

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

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

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

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

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

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

       MSG_TRUNC
              Возвращает реальную длину пакета, даже если она была больше, чем
              предоставленный буфер.  Этот флаг можно  использовать  только  с
              пакетными протоколами.

       MSG_ERRQUEUE
              Получить пакет из очереди ошибок.

       MSG_NOSIGNAL
              Этот  флаг  отключает возникновение сигнала SIGPIPE на потоковых
              сокетах, если другая сторона вдруг исчезает.

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

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

              Ошибка хранится в структуре 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
              {
                  __u32           ee_errno;   /* номер ошибки */
                  __u8            ee_origin;  /* источник её происхождения */
                  __u8            ee_type;    /* тип */
                  __u8            ee_code;    /* код */
                  __u8            ee_pad;
                  __u32           ee_info;    /* дополнительная информация */
                  __u32           ee_data;    /* прочие данные */
              };

              struct sockaddr *SOCK_EE_OFFENDER(struct sock_extended_err *);

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

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

       Системный вызов recvmsg использует структуру  msghdr  для  того,  чтобы
       минимизировать количество непосредственно передаваемых параметров.  Эта
       структура определена в <sys/socket.h> так:

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

       Здесь msg_name и msg_namelen задают адрес  назначения,  если  сокет  не
       соединен;  в  параметре  msg_name  можно  передать  NULL, если имена не
       требуются или вообще нежелательны. Поля msg_iov и msg_iovlen  описывают
       точки  scatter-gather,  что  обсуждается в readv(2).  Поле msg_control,
       имеющее длину msg_controllen, указывает на буфер для других  сообщений,
       связанных  с  управлением  протоколов,  или  на буфер для разнообразных
       вспомогательных  данных.   Когда  вызывается   recvmsg,   в   параметре
       msg_controllen  должна  находиться  длина  доступного буфера, чей адрес
       передается в msg_control; при  успешном  завершении  в  этом  параметре
       будет находиться длина последовательности контрольных сообщений.

       Сообщения имеют такую форму:

              struct cmsghdr {
                  socklen_t   cmsg_len;   /* количество байт данных, */
                                          /* включая hdr */
                  int         cmsg_level; /* протокол  */
                  int         cmsg_type;  /* тип, зависящий от протокола */
              /* дальше следует
                  u_char      cmsg_data[]; */
              };

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

       Например, Linux использует этот  механизм  вспомогательных  данных  для
       того, чтобы передавать через Unix-сокеты расширенные ошибки, флаги IP и
       файловые дескрипторы.

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

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

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

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

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

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

       MSG_DONTWAIT
              Разрешает  неблокирующий режим.  Если операция могла бы привести
              к  блокировке,  возвращается  EAGAIN  (этот  режим  можно  также
              включить  с  помощью  O_NONBLOCK  и  функции  F_SETFL системного
              вызова fcntl(2)).

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

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

ОШИБКИ

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

       EBADF   Аргумент s является неверным дескриптором.

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

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

       ENOTSOCK
               Аргумент s не является сокетом.

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

       EINTR   Прием  данных  был  прерван  сигналом,  а  данные  еще  не были
               доступны.

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

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

СООТВЕТСТВИЕ СТАНДАРТАМ

       4.4BSD (эти системные вызовы впервые появились в 4.2BSD).

ЗАМЕЧАНИЕ

       Вышеприведенные  прототипы соответствуют glibc2.  Стандарт SUS согласен
       с ними, за исключением того, что там возвращаемые  значения  определены
       как  ssize_t  (тогда  как  в  BSD 4.x, libc4 и libc5 они определены как
       int).  Аргумент flags является int в BSD 4.x, но unsigned int в libc4 и
       libc5.  Аргумент len является int в BSD 4.x, но size_t в libc4 и libc5.
       Аргумент fromlen является int * в BSD  4.x,  libc4  и  libc5.   Текущее
       определение,  socklen_t, было изобретено в POSIX (см. также accept(2)).

СМОТРИ ТАКЖЕ

       fcntl(2), read(2), select(2), getsockopt(2), socket(2), cmsg(3)

ПЕРЕВОД

       Copyright (C) Alexey Mahotkin <alexm@hsys.msk.ru> 1999-2001