recvmsg 子例程

用途

从任何套接字接收消息。

标准 C 库 (libc.a)

语法

#include <sys/socket.h>
int recvmsg ( Socket,  Message,  Flags)
int Socket;
struct msghdr Message [ ];
int Flags;
int recvmmsg ( Socket, MessageVec, Num_msg,  Flags, Timeout)
int Socket;
struct mmsghdr MessageVec [ ];
unsigned int Num_msg ;
int Flags;
struct timespec *Timeout

描述

recvmsg 子例程从未连接或已连接的套接字接收消息。 recvmsg 子例程返回消息的长度。 如果消息太长而无法容纳在提供的缓冲区中,那么可能会根据发出消息的套接字的类型来截断多余的字节。

如果套接字上没有可用的消息,那么 recvmsg 子例程将等待消息到达。 如果套接字是非分块的,并且没有可用的消息,那么 recvmsg 子例程不成功。

使用 select 子例程来确定何时到达更多数据。

recvmsg 子例程使用 msghdr 结构来减少直接提供的参数的数目。 msghdr 结构在sys/socket.h 文件中定义。 在 BSD 4.3 Reno 中,已修改 msghdr 结构的大小和成员。 想要启动旧结构的应用程序需要在定义 COMPAT_43 的情况下进行编译。 缺省行为是 BSD 4.4的行为。

必须在将 _BSD 宏设置为特定值的情况下编译包含 recvmsg 子例程的所有应用程序。 可接受的值为 43 和 44。 此外,所有套接字应用程序都必须包含 BSD libbsd.a 库。

recvmmsg 子例程是 recvmsg 子例程的扩展,它接收从套接字到调用者套接字的多条消息。 此子例程对某些应用程序具有性能优势。 recvmmsg 子例程支持在接收操作期间等待的超时。

sockfd 参数是从中接收数据的套接字的文件描述符。 msgvec 自变量是指向 mmsghdr 结构数组的指针。 这些参数在 sys/socket.h file中定义。

recvmmsg 子例程返回时,将更新 msgvec 结构的连续元素以包含有关每个接收到的消息的信息。 msg_len 字段包含接收到的消息的大小。 如 recvmsg 子例程中所述,更新 msg_hdr 字段的子字段。 recvmsg 调用的返回值指示要更新的 msgvec 字段的元素数。

参数

描述
套接字 指定套接字的唯一名称。
消息 指向 msghdr 结构的地址,该结构包含入局消息的地址和发件人地址的空间。
标志 允许子例程对消息的接收进行控制。 用于接收调用的 Flags 参数通过从逻辑上对以下列表中显示的一个或多个值进行 OR 运算来构成:
MSG_OOB
处理频带外数据。 频带外数据的重要性取决于协议。
MSG_PEEK
对传入数据进行 peeks。 数据将继续被视为未读,并将由下一次调用 recv () 或类似函数来读取。
MSG_WAITALL
请求在读取所请求的字节数之前不返回该函数。 仅当捕获到信号,终止连接或套接字的错误处于暂挂状态时,该函数返回的字节数才能少于所请求的字节数。
MSG_WAITFORONE
在接收到第一条消息后打开 MSG_DONTWAIT 标志。

/sys/socket.h 文件包含 Flags 参数的可能值。

MessageVec 指向 mmsghdr 结构的数组,其中包含入局消息的 msghdr 结构,发件人地址的空间以及表示数组中元素总数的值。
消息数 定义在将控件返回到调用套接字之前要接收的消息数。
超时

timeout 自变量指向 timespec 结构,该结构定义接收操作的超时值 (以秒加纳秒为单位指定)。 如果超时值为 NULL ,那么将阻塞对 recvmmsg 子例程的调用,直到接收到 vlen 消息或超时值到期为止。 对 recvmmsg 子例程的非分块调用将读取发送方套接字处的所有可用消息 (限制由 vlen 参数指定) ,并立即从子例程返回到调用函数。

返回值

成功完成 recvmsg 子例程后,将返回消息长度 (以字节为单位) ,对于 recvmmsg 子例程,将返回接收到的消息数。

如果 recvmsgrecvmmsg 子例程不成功,那么子例程处理程序将执行以下函数:

  • 会向调用程序返回-1的值。
  • 将指示特定错误的错误代码移动到 errno 全局变量中。

错误代码

如果发生以下任何错误代码,那么 recvmsg 子例程不成功:

错误 描述
EBADF Socket 参数无效。
ECONNRESET 远程同级强制关闭连接。
Efault Address 参数不在用户地址空间的可写部分中。
EINTR 在任何数据可用于接收之前,通过传递信号中断了 recvmsg 子例程。
EINVAL msghdr 结构的长度无效,或者设置了 MSG_OOB 标志,并且没有可用的频带外数据。
EMSGSIZE Message 指向的 msghdr 结构的 msg_iovlen 成员小于或等于 0 ,或者大于 IOV_MAX
ENOBUF 系统中没有足够的可用资源来执行操作。
ENOPROTOOPT 该协议不受 64 位支持。
ENOTCONN 在未连接的 SOCK_STREAM 套接字上尝试接收。
ENOTSOCK Socket 参数引用文件,而不是套接字。
EOPNOTSUPP SOCK_DGRAM 套接字设置 MSG_OOB 标志,或为任何 AF_UNIX 套接字设置 MSG_OOB 标志。
ETIMEDOUT 连接建立期间连接超时,或者活动连接上存在传输超时。
EWOULDBLOCK 套接字被标记为无阻塞,并且不存在要接受的连接。