linux:利用socketpair来在进程间传递描述符

1.socketpair

2.sendmsg/recvmsg

3.UNIX域套接字传递描述字

功能:创建一个圈双工的流管道

原型:

int socketpair(int domain, int type, int protocol, int sv[2]);

参数 domain :协议家族

   type: 套接字种类

   protocol:协议种类

   sv:返回的套接字对

返回值: 成功返回0, 失败返回-1

通过sockpair创建的全双通管道可以实现父子间进程通讯

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define ERR_EXIT(m)     do {         perror(m);        exit(EXIT_FAILURE);    }while(0)

int main(int argc, const char *argv[])
{
    int sockfds[2];
    int ret = socket(PF_UNIX, SOCK_STREAM, 0, sockfds);
    
    if(ret == -1)
        ERR_EXIT("sockpair");
    pid_t pid;
    pid = fork();
    if(pid == -1)
        ERR_EXIT("fork");
    if(pid > 0)
    {
        int val = 0;
        close(sockfd[1]);
        while(1)
        {
            ++val;
            printf("sending data:  %d\n", val);
            write(sockfds[0], &val, sizeof(val));
            read(sockfd[0], &val, sizeof(val));
            printf("data received: %d\n", val);
            sleep(1);
        }
    }else if(pid == 0)
    {
        int val;
        close(sockfds[0]);
        while(1)
        {
            read(sockfds[1], &val, sizeof(val));
            ++val;
            write(sockfds[1], &val, sizeof(val));
        }
    }

    return 0;
    
}

会发现val的值不停的增加,并且在父子间进程被传递;

 

下面我们来看一下更加强大的sendmsg函数

ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);

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 */
};

参数解释:

1.void         *msg_name;       /* optional address */ 
   socklen_t     msg_namelen;

这两个参数确定发送的地址

2。struct iovec *msg_iov;        /* scatter/gather array */

我们要发送的数据存放在这个结构体中

struct iovec {
          void  *iov_base;    /* Starting address */  这个相当于缓冲区
          size_t iov_len;     /* Number of bytes to transfer */ 缓冲区长度
      };

结构如上
++++++

这是一个msghdr的示意图

 

技术分享

3.再下面几个数据时辅助信息。

我们通过自己封装sendmsg实现传递描述符

自己写一个send

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。