这两个函数是最通用的I/O函数。实际上,可以用recvmsg代替read、readv、recv和redvfrom。同样,各种输出函数都可以用sendmsg取代
#include<sys/socket.h>
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
ssize_t sendmsg(int sockfd, struct msghdr *msg, int flags);
成功返回读入或写出的字节数,出错时返回-1
这两个函数把大部分参数包装到一个msghdr结构中:
struct msghdr
{
void *msg_name; //protocol address
socklen_t msg_namelen; //sizeof protocol address
struct iovec *msg_iov; //scatter /gather array
size_t msg_iovlen; //elements in msg_iov
void *msg_control;
socklen_t msg_controllen;
int msg_flags; //flags returned by recvmsg()
};
re
msg_name和msg_namelen成员用于未经连接的套接口,它们与recvfrom、sendto的第五和第六个参数类似;msg_name指向一个套接口地址结构,调用者在其中存放对sendmsg来说是目的方的协议地址,对recvmsg来说是发送方的协议地址。如果不需要指明协议地址,msg_name应被设置为空指针。msg_namelen对sendmsg是一个值,而对recvmsg是一个值-结果参数
msg_iov和msg_iovlen成员指明输入或输出的缓冲区数组(iovec结构的数组),这与readv、writev的第二个和第三个参数相似。
msg_control和msg_controllen成员指明可选的辅助数据的位置和大小,msg_controlllen对recvmsg是一个值-结果参数
使用recvmsg和sendmsg时我们必须区别两个标志变量:传值的flags参数和msghdr结构中的msg_flags成员,它是以引用方式传递的
(1)msg_flags只用于recvmsg。调用recvmsg时,flags参数拷贝到msg_flags成员,而且内核用这个值进行接收处理,接着它的值会根据recvmsg的结果而更新
(2)sendmsg会忽略msg_flags成员,因为它在进行输出处理进使用flags参数。这意味着如果我们在调用 sendmsg时要设置MSG_DONTWAIT标志,应将flags设成该值,设置msg_flags为该值无效。