转载自:https://blog.youkuaiyun.com/stone8761/article/details/72780863
https://www.cnblogs.com/wenqiang/p/6306727.html
user_msghdr结构体,就是用户层的msghdr结构体。
E:\linux-4.1.45\linux-4.1.45\include\linux\socket.h
struct user_msghdr {
void __user *msg_name; /* ptr to socket address structure */
int msg_namelen; /* size of socket address structure */
struct iovec __user *msg_iov; /* scatter/gather array */
__kernel_size_t msg_iovlen; /* # elements in msg_iov */
void __user *msg_control; /* ancillary data */
__kernel_size_t msg_controllen; /* ancillary data buffer length */
unsigned int msg_flags; /* flags on received message */
};
msg_name:指针,指向socket地址结构
msg_namelen:msg_name指向的socket地址结构的长度,例如netlink传递消息时,为sizeof(struct sockaddr_nl)
msg_iov:指向待发送/接收数据缓冲区,缓冲区由一个分散/聚集数组构成,
msg_ioven:msg_iov缓冲区数组元素个数
struct iovec
{
void __user *iov_base; /* BSD uses caddr_t (1003.1g requires void *) */
__kernel_size_t iov_len; /* Must be size_t (1003.1g) */
};
iovec结构用来描述一个输入/输出缓冲区,iov_base:指向数据缓存区,iov_len:表示该缓冲区的长度。一个报文,可以由多个数据缓存区存储。
msg_control、msg_controllen、msg_flags先不管。
分散/聚集
参考:https://www.jianshu.com/p/c76b13aaad77
分散:从channel读取数据,将数据读取至多个buffer中。
聚合:将多个buffer数据写入到一个channel中。
内核中的msghdr结构体
/*
* As we do 4.4BSD message passing we use a 4.4BSD message passing
* system, not 4.3. Thus msg_accrights(len) are now missing. They
* belong in an obscure libc emulation or the bin.
*/
struct msghdr {
void *msg_name; /* ptr to socket address structure */
int msg_namelen; /* size of socket address structure */
struct iov_iter msg_iter; /* data */
void *msg_control; /* ancillary data */
__kernel_size_t msg_controllen; /* ancillary data buffer length */
unsigned int msg_flags; /* flags on received message */
struct kiocb *msg_iocb; /* ptr to iocb for async requests */
};