ИМЯ
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
является
битовой
маской и
может
содержать
следующие
флаги:
- MSG_CONFIRM
(начиная с Linux
2.3.15)
- Сообщить
уровню
связи, что
процесс
пересылки
произошел:
вы
получили
успешный
ответ с
другой
стороны.
Если
уровень
связи не
получит
его, то он
будет
регулярно
перепроверять
наличие
ответной
стороны
(например
посредством
однонаправленной
передачи ARP).
Это
работает
только с
сокетами
SOCK_DGRAM и SOCK_RAW и в
настоящее
время
реализовано
только для
IPv4 и IPv6. В arp(7)
представлена
более
подробная
информация.
- MSG_DONTROUTE
- Не
использовать
маршрутизацию
для
отправки
пакета, а
посылать
его только
на узлы
локальной
сети.
Обычно это
используется
в
диагностических
программах
и
программах
маршрутизации.
Этот флаг
определён
только для
маршрутизируемых
семейств
протоколов;
пакетные
сокеты не
используют
маршрутизацию.
- MSG_DONTWAIT
(начиная с Linux
2.2)
- Включить
неблокирующий
режим. Если
операция
могла бы
привести к
блокировке,
возвращается
EAGAIN или EWOULDBLOCK.
Такое
поведение
подобно
заданию
флага O_NONBLOCK (в
fcntl(2)
операцией
F_SETFL), но
отличие в
том, что MSG_DONTWAIT
указывается
в вызове, а
O_NONBLOCK
задаётся в
описании
открытого
файла
(смотрите
open(2)), что
влияет на
все нити
вызывающего
процесса, а
также на
другие
процессы, у
которых
есть
файловые
дескрипторы,
ссылающиеся
на это
описание
открытого
файла.
- MSG_EOR
(начиная с Linux
2.2)
- Завершить
запись (record)
(если
поддерживается,
например в
сокетах
типа SOCK_SEQPACKET).
- MSG_MORE
(начиная с Linux
2.4.4)
- Вызывающий
имеет
дополнительные
данные для
отправки.
Этот флаг
используется
с сокетами
TCP для
получения
такого же
эффекта
как с
параметром
сокета TCP_CORK
(см. tcp(7)), с той
разницей,
что этот
флаг можно
устанавливать
при каждом
вызове.
- Начиная с Linux
2.6 этот флаг
также
поддерживается
для
сокетов UDP и
информирует
ядро, о том
что нужно
упаковать
все
отправляемые
данные
вызовов с
этим
флагом в
одну
дейтаграмму,
которая
передаётся
только
когда
выполняется
вызов без
указания
этого
флага
(смотрите
также
описание
параметра
сокета UDP_CORK в
udp(7)).
- MSG_NOSIGNAL
(начиная с Linux
2.2)
- Не
генерировать
сигнал SIGPIPE,
если
сторона
потокоориентированного
сокета
закрыла
соединение.
Ошибка EPIPE
по
прежнему
возвращается.
Это
создаёт
поведение
как при
использовании
sigaction(2) для
игнорирования
SIGPIPE, но MSG_NOSIGNAL
является
свойством
вызова, а
установка
SIGPIPE в
атрибутах
процесса
влияет на
все нити
процесса.
- MSG_OOB
- Послать
внепоточные
данные,
если сокет
это
поддерживает
(как,
например,
сокеты
типа SOCK_STREAM);
протокол
более
низкого
уровня
также
должен
поддерживать
внепоточные
данные.
Определение
структуры
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
устанавливается
в
соответствующее
значение.
ОШИБКИ
Здесь
представлено
несколько
стандартных
ошибок,
возвращаемых
с уровня
сокетов.
Могут
также
появиться
другие
ошибки,
возвращаемые
из
соответствующих
модулей
протоколов;
их
описание
находится
в
соответствующих
справочных
страницах.
- EACCES
- (для
доменных
сокетов UNIX,
которые
идентифицируются
по имени
пути) Нет
прав на
запись в
файл
сокета
назначения
или в одном
из
каталогов
пути
запрещён
поиск (см.
также path_resolution(7)).
- (для
сокетов UDP)
Попытка
отправки
по
сетевому/широковещательному
адресу, как
будто это
был
однозначный
(unicast) адрес.
- EAGAIN
или EWOULDBLOCK
- Сокет
помечен
как
неблокирующий,
но
запрошенная
операция
привела бы
к
блокировке.
POSIX.1-2001
допускает
в этих
случаях
возврат
ошибки и не
требует,
чтобы эти
константы
имели
одинаковое
значение,
поэтому
переносимое
приложение
должно
проверять
обе
возможности.
- EAGAIN
- (доменные
датаграммные
сокеты
Интернета)
Сокет,
указанный
sockfd, ранее не
был
привязан к
адресу и
при
попытке
привязать
его к
эфемеридному
порту, было
определено,
что все
номера в
диапазоне
эфемеридных
портов уже
используются.
Смотрите
обсуждение
/proc/sys/net/ipv4/ip_local_port_range в ip(7).
- EALREADY
- Сейчас
выполняется
другая
операция Fast
Open.
- EBADF
- Значение
sockfd не
является
правильным
открытым
файловым
дескриптором.
- ECONNRESET
- Соединение
сброшено
другой
стороной.
- EDESTADDRREQ
- Сокет в
режиме без
установления
соединения
и адрес
второй
стороны не
задан.
- EFAULT
- В
аргументе
указано
неверное
значение
адреса
пользовательского
пространства.
- EINTR
- Получен
сигнал до
начала
передачи
данных;
смотрите
signal(7).
- EINVAL
- Передан
неверный
аргумент.
- EISCONN
- Сокет в
режиме с
установлением
соединения
уже
выполнил
подключение,
но указан
получатель
(теперь или
возвращается
эта ошибка,
или
игнорируется
указание
получателя).
- EMSGSIZE
- Для типа
сокета
требуется,
чтобы
сообщение
было
отослано
за время
одной
операции
(атомарно),
а размер
сообщения
не
позволяет
этого.
- ENOBUFS
- Исходящая
очередь
сетевого
интерфейса
заполнена.
Обычно это
означает,
что
интерфейс
прекратил
отправку,
но это
может быть
также
вызвано
временной
перегрузкой
сети.
Обычно, в Linux
этого не
происходит.
Пакеты
просто
отбрасываются,
когда
очередь
устройства
переполняется.
- ENOMEM
- Больше нет
доступной
памяти.
- ENOTCONN
- Сокет не
подключён
и
назначение
не задано.
- ENOTSOCK
- Файловый
дескриптор
sockfd
указывает
не на
каталог.
- EOPNOTSUPP
- Один из
битов в
аргументе
flags не может
устанавливаться
для этого
типа
сокета.
- EPIPE
- Локальный
сокет,
ориентированный
на
соединение,
был закрыт.
В этом
случае
процесс
также
получит
сигнал SIGPIPE,
если не
установлен
флаг MSG_NOSIGNAL.
СООТВЕТСТВИЕ
СТАНДАРТАМ
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.
СМОТРИТЕ
ТАКЖЕ
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)