Книга: UNIX: разработка сетевых приложений
14.3. Функции recv и send
14.3. Функции recv и send
Эти две функции аналогичны стандартным функциям read
и write
, но для них требуется дополнительный аргумент.
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buff, size_t nbytes, int flags);
ssize_t send(int sockfd, const void *buff, size_t nbytes, int flags);
Обе функции возвращают: количество прочитанных или записанных байтов в случае успешного выполнения, -1 в случае ошибки
Первые три аргумента функций recv
и send
совпадают с тремя первыми аргументами функций read и write. Аргумент flags
либо имеет нулевое значение, либо формируется в результате применения операции логического ИЛИ к константам, представленным в табл. 14.1.
Таблица 14.1. Аргумент flags для функций ввода-вывода
flags | Описание | recv | send |
---|---|---|---|
MSG_DONTROUTE | He искать в таблице маршрутизации | • | |
MSG_DONTWAIT | Только эта операция является неблокируемой | • | • |
MSG_OOB | Отправка или получение внеполосных данных | • | |
MSG_PEEK | Просмотр приходящих сообщений | • | |
MSG_WAITALL | Ожидание всех данных | • |
? MSG_DONTROUTE
. Этот флаг сообщает ядру, что получатель находится в нашей сети, и поэтому не нужно выполнять поиск в таблице маршрутизации. Дополнительную информацию об этом свойстве мы приводим при описании параметра сокета SO_DONTROUTE
(см. раздел 7.5). Это свойство можно включить для одной операции вывода с флагом MSG_DONTROUTE
или для всех операций вывода данного сокета, используя указанный параметр сокета.
? MSG_DONTWAIT
. Этот флаг указывает, что отдельная операция ввода-вывода является неблокируемой. Таким образом, отпадает необходимость включать флаг отсутствия блокировки для сокета, выполнять операцию ввода-вывода и затем выключать флаг отсутствия блокировки. Неблокируемый ввод-вывод мы опишем в главе 15 вместе с включением и выключением флага отсутствия блокировки для всех операций ввода-вывода через сокет.
ПРИМЕЧАНИЕ
Этот флаг введен в Net/3 и может не поддерживаться в некоторых системах.
? MSG_OOB
. С функцией send
этот флаг указывает, что отправляются внеполосные данные. В случае TCP в качестве внеполосных данных должен быть отправлен только 1 байт, как показано в главе 21. С функцией recv
этот флаг указывает на то, что вместо обычных данных должны читаться внеполосные данные.
? MSG_PEEK
. Этот флаг позволяет нам просмотреть пришедшие данные, готовые для чтения, при этом после выполнения функции recv
или recvfrom
данные не сбрасываются (при повторном вызове этих функций снова возвращаются уже просмотренные данные). Подробнее мы поговорим об этом в разделе 14.7.
? MSG_WAITALL
. Этот флаг был впервые введен в 4.3BSD Reno. Он сообщает ядру, что операция чтения должна выполняться до тех пор, пока не будет прочитано запрашиваемое количество байтов. Если система поддерживает этот флаг, мы можем опустить функцию readn
(см. листинг 3.9) и заменить ее макроопределением
#define readn(fd, ptr, n) recv(fd, ptr, n, MSG_WAITALL)
Даже если мы задаем флаг MSG_WAITALL
, функция может возвратить количество байтов меньше запрашиваемого в том случае, если или перехватывается сигнал, или соединение завершается, или есть ошибка сокета, требующая обработки.
Существуют дополнительные флаги, используемые протоколами, отличными от TCP/IP. Например, транспортный уровень OSI основан на записях (а не на потоке байтов, как TCP), и для операций вывода поддерживает флаг MSG_EOR
, задающий конец логической записи.
С аргументом flags
связана одна фундаментальная проблема: он передается по значению и не является аргументом типа «значение-результат». Следовательно, он может использоваться только для передачи флагов от процесса к ядру. Ядро не может передать флаги обратно процессу. Это не представляет проблемы с TCP/IP, поскольку очень редко бывает необходимо передавать флаги обратно процессу от ядра. Но когда к 4.3BSD Reno были добавлены протоколы OSI, появилась необходимость возвращать процессу флаг MSG_EOR
при операции ввода. В 4.3BSD Reno было принято решение оставить аргументы для общеупотребительных функций (recv
и recvfrom
) как есть и изменить структуру msghdr
, которая используется с функциями recvmsg
и sendmsg
. В разделе 14.5 мы увидим, что в эту структуру был добавлен целочисленный элемент msg_flags
, и поскольку структура передается по ссылке, ядро может изменить флаги, содержащиеся в этом элементе, по завершении функции. Это значит также, что если процессу необходимо, чтобы флаги изменялись ядром, процесс должен вызвать функцию recvmsg
вместо вызова функции recv
или recvfrom
.
- Глава 14 Дополнительные функции ввода-вывода
- 14.5. Функции recvmsg и sendmsg
- 8.2. Функции recvfrom и sendto
- Аргументы функции в Python
- 3. Функции
- Новые функции API для работы с Blob и массивами
- Data sending and control session
- Математические функции
- Размытые функции
- 7.3. Финансовые функции
- 4.3. Логические функции и таблицы истинности
- B1.7. Функции обработки ошибок