由于笔者才疏学浅,本文难免存在遗漏之处,欢迎大家留言指正。
起初知道进程间可以传递文件描述符的时候就很好奇是怎么做到的,最近查阅了一些文章,此处做个笔记,方便日后回顾。文中结合nginx代码,具体分析一下如何在不同进程之间传递文件描述符。
一、浅谈sendmsg和recvmsg
由于nginx中通过sendmsg和recvmsg的辅助信息来传递文件描述符,此处先简要介绍这两个接口。
1、函数原型
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
recvmsg和sendmsg都可以用于连接套接字和非连接的套接字,具体可参考recvmsg和sendmsg。下面主要介绍struct msghdr结构,主要用来传递一些辅助信息,进程间套接字的传递就是通过辅助信息来传递的。
2、struct msghdr结构
struct msghdr {
void *msg_name; /* optional address */
socklen_t msg_namelen; /* size of address */
struct iovec *msg_iov; /* scatter/gather array */
size_t msg_iovlen; /* # elements in msg_iov */
void *msg_control; /* ancillary data, see below */
size_t msg_controllen; /* ancillary data buffer len */
int msg_flags; /* flags on received message */
};
此处仅介绍msg_control和msg_controllen这两个成员,msg_control指向一段内存空间,msg_controllen表示这段内存的大小。sendmsg通过msg.msg_control来传递辅助信息,recvmsg通过msg.msg_control来接收辅助信息。msg.msg_control指向的空间,由一个或多个辅助数据对象组成。其中辅助数据对象由struct cmsghdr结构、辅助数据以及填充字段组成。下图包含两个辅助数据对象。
3、struct cmsghdr结构
struct cmsghdr {
socklen_t cmsg_len; /* 结构头、填充字节和辅助数据的大小,这个值由CMSG_LEN()宏计算 */
int cmsg_level; /* 表明了原始的协议级别(如ÿ