标签:不为 空指针 技术 array 字节 sg函数 soc 输出 socket
复习 socket 编程的时候发现了以前没有留意到的 2个函数:recvmsg
和 sendmsg
先来看看函数原型:
#include <sys/types.h>
#include <sys/socket.h>
...
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
...
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
struct msghdr {
void *msg_name; // protocol address
socklen_t msg_namelen; // size of protocol address
struct iovec *msg_iov; // scatter/gather array
int msg_iovlen; // elements in msg_iov
void *msg_control; // ancillary data (cmsghdr struct)
socklen_t msg_controllen; // length of ancillary data
int msg_flags; // flags returned by recvmsg()
};
这两个成员用于套接字未连接的场合(如未连接 UDP 套接字)。它们类似 recvfrom 和 sendto 的第五个和第六个参数:
这两个成员指定输入或输出缓冲区数组(即iovec结构数组),类似 readv 或 writev 的第二个和第三个参数。
这两个成员指定可选的辅助数据的位置和大小。msg_controllen 对于 recvmsg 是一个值-结果参数。
对于 recvmsg 和 sendmsg,必须区别它们的两个标志变量:
只有 recvmsg 使用 msg_flags 成员。recvmsg 被调用时,flags 参数被复制到 msg_flags 成员,并由内核使用其值驱动接收处理过程。内核还依据 recvmsg 的结果更新 msg_flags 成员的值。
sendmsg 则忽略 msg_flags 成员,因为它直接使用 flags 参数驱动发送处理过程。这一点意味着如果想在某个 sendmsg 调用中设置 MSG_DONTWAIT 标志,那就把 flags 参数设置为该值,把 msg_flags 成员设置为该值不起作用。
recvmsg 返回的 7 个标志如下:
下图展示了一个 msghdr 结构以及它指向的各种信息。图中假设进程即将对一个 UDP 套接字调用 recvmsg:
图中给协议地址分配了 16 个字节,给辅助数据分配了 20 个字节。为缓冲数据初始化了一个由 3 个 iovec 结构构成的数组:第一个指定一个 100 字节的缓冲区,第二个指定一个 60 字节的缓冲区,第三个指定一个 80 字节的缓冲区。假设已为这个套接字设置了 IP_RECVDSTADDR 套接字选项,以接收所读取 UDP 数据包的目的 IP 地址。
假设从 198.38.100:2000 到达一个 170 字节的 UDP 数据报,它的目的地是我们的 UDP 套接字,目的 IP 地址为 206.168.112.96.下图展示了 recvmsg 返回时 msghdr 结构中的所有信息。
图中被 recvmsg 修改过的字段标上了阴影。从第一幅图到第二幅图的变动包括以下几点:
标签:不为 空指针 技术 array 字节 sg函数 soc 输出 socket
原文地址:https://www.cnblogs.com/schips/p/12539824.html