1。函数及结构介绍
开发通信程序,经常遇到服务程序的开发,常见使用进程池及线程池,下面介绍一对在进程池应用非常有用的函数,sendmsg/recvmsg,可以通过这组函数在进程中传递socket描述符。可以在主进程使用多路复用侦听socket事件,将读写事件句柄传递给工作进程进行处理。
在使用函数前先来看一看下面的结构
struct msghdr {
void *msg_name; /* Socket name */
int msg_namelen; /* Length of name */
struct iovec *msg_iov; /* Data blocks */
__kernel_size_t msg_iovlen; /* Number of blocks */
void *msg_control; /* Per protocol magic (eg BSD file descriptor passing) */
__kernel_size_t msg_controllen; /* Length of cmsg list */
unsigned msg_flags;
};
msg_name,msg_namelen指向地址指针,用于套接口未连接场合如UPD套接字,如果无需指明协议地址如TCP协议,msg_name通常为NULL;
msg_iov,msg_iovlen指定输入输出缓冲区数组及长度;
msg_control, msg_controllen指定可选辅助数据的位置及大小,也称为控制信息;
msg_flags 只有recvmsg使用msg_flags成员,recvmsg被调用时,flags参数被拷贝到msg_flags成员,sendmsg忽略此成员,因为它使用flags参数驱动发送处理过程;
在使用recvmsg/sendmsg传递socket描述符时,msg_control成员指向的缓冲区被填以一个cmsghdr的结构:
struct cmsghdr
{
socklen_t cmsg_len;
int cmsg_level;
int cmsg_type;
/*下面可加入传输入数据,此处可写入描述符*/
}