| SEND(2) | Руководство программиста Linux | SEND(2) | 
send, sendto, sendmsg - отправляет сообщения в сокет
#include <sys/types.h> #include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
               const struct sockaddr *dest_addr, socklen_t addrlen);
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
Системные вызовы send(), sendto() и sendmsg() используются для пересылки сообщений в другой сокет.
Вызов send() можно использовать, только если сокет находится в состоянии соединения (то есть известен получатель). Вызов send() отличается от write(2) только наличием аргумента flags. Если значение flags равно нулю, то вызов send() эквивалентен write(2). Также, вызов
send(sockfd, buf, len, flags);
эквивалентен
sendto(sockfd, buf, len, flags, NULL, 0);
Аргумент sockfd представляет файловый дескриптор сокета отправления.
Если sendto() используется с сокетом в режиме с установлением соединения (SOCK_STREAM, SOCK_SEQPACKET), то аргументы dest_addr и addrlen игнорируются (и может быть возвращена ошибка EISCONN, если их значения не равны NULL и 0) и возвращается ошибка ENOTCONN, если соединение через сокет не установлено. Иначе в dest_addr задаётся адрес назначения и его размер в addrlen. Для sendmsg() адрес назначения указывается в msg.msg_name, а его размер в msg.msg_namelen.
У send() и sendto() сообщение находится в buf, а его длина в len. У sendmsg() сообщение указывается в элементах массива msg.msg_iov. Вызов sendmsg() также позволяет отправлять вспомогательные данные (так называемую управляющую информацию).
Если сообщение слишком длинно для передачи за раз через используемый нижележащий протокол, то возвращается ошибка EMSGSIZE и сообщение не передаётся.
Неудачная отправка с помощью send() никак не отмечается. При обнаружении локальных ошибок возвращается значение -1.
Когда сообщение не помещается в буфер отправки сокета, выполнение блокируется в send(), если сокет не находится в неблокирующем режиме. Если сокет находится в неблокирующем режиме, то возвращается ошибка EAGAIN или EWOULDBLOCK. Для выяснения, возможна ли отправка данных, можно использовать вызов select(2).
Аргумент flags является битовой маской и может содержать следующие флаги:
Определение структуры msghdr, используемой sendmsg():
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 должен быть указан размер адреса. Для подключённого сокета значения этих полей должны быть равны NULL и 0, соответственно.
В полях msg_iov и msg_iovlen задаются места приёма/передачи, как для writev(2).
Управляющую информацию можно посылать через поля msg_control и msg_controllen. Максимальная длина управляющего буфера, которую поддерживает ядро, ограничена значением /proc/sys/net/core/optmem_max; см. socket(7).
Поле msg_flags игнорируется.
При успешном выполнении эти вызовы возвращают количество отправленных байт. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.
Здесь представлено несколько стандартных ошибок, возвращаемых с уровня сокетов. Могут также появиться другие ошибки, возвращаемые из соответствующих модулей протоколов; их описание находится в соответствующих справочных страницах.
4.4BSD, SVr4, POSIX.1-2001. Эти интерфейсы впервые появились в 4.2BSD.
В POSIX.1-2001 описаны только флаги MSG_OOB и MSG_EOR. В POSIX.1-2008 добавлено описание MSG_NOSIGNAL. Флаг MSG_CONFIRM является нестандартным расширением Linux.
В соответствие с POSIX.1-2001 поле msg_controllen структуры msghdr должно иметь тип socklen_t, но в настоящее время в glibc оно имеет тип size_t.
В sendmmsg(2) можно найти информацию о специальном системном вызове Linux, который можно использовать для передачи нескольких дейтаграмм за один вызов.
Linux может вернуть EPIPE вместо ENOTCONN.
Пример использования sendto() показан в getaddrinfo(3).
fcntl(2), getsockopt(2), recv(2), select(2), sendfile(2), sendmmsg(2), shutdown(2), socket(2), write(2), cmsg(3), ip(7), ipv6(7), socket(7), tcp(7), udp(7), unix(7)
| 2017-09-15 | Linux |