进程间传递文件描述符的方法

摘要:
UNP描述了三种传输描述符的方法:1.使用ioctl2.对于父子进程使用套接字对。3.如果没有关系,请使用unixsocket。这里介绍第三种方法,因为它相对复杂和繁琐:UNP描述了这一步骤:1.创建unixstreamsocket,其中一个必须是绑定和侦听。2.使用sendmsg和recvmsg接口传输描述符3.注意相关的工具宏和结构。阅读1了解详细信息

UNP讲述了三种传递描述符的方法:

1.使用ioctl

2.如果是父子关系进程用socketpair

3.没关系则使用unix socket

这里介绍一下第三种,因为相对复杂繁琐:

  UNP里讲述了这个步骤:

  1.创建unix stream socket,其中要有一个是bind且在listen的。

  2.使用sendmsg与recvmsg接口传送描述符

  3.需要注意的是相关的工具宏和struct.具体翻阅14.5节.

下面我自己写的两个示例代码,图一接收文件描述符并输出hello来验证,图二是要一个临时文件作为参数传入,并发送该文件的套接字给图一的进程.值得注意的是,在发送时,该文件描述符的引用计数会增加,因此关闭进程2并不会导致进程1使用此描述符.

extern "C"
{
#include <unp.h>
}

int main(int argc, char **argv)
{
    sockaddr_un seraddr;
    bzero(&seraddr, sizeof(seraddr));
    seraddr.sun_family = AF_UNIX;
    strcpy(seraddr.sun_path, UNIXSTR_PATH);
    int lisfd = socket(AF_UNIX, SOCK_STREAM, 0);
    int on = 1;
    unlink(UNIXSTR_PATH);
    Bind(lisfd, (SA *)&seraddr, sizeof(seraddr));
    Listen(lisfd, LISTENQ);
    sockaddr_un cliaddr;
    socklen_t addrlen;
    int connfd = Accept(lisfd, (SA *)&cliaddr, &addrlen);
    msghdr msg;
    iovec iov;
    msg.msg_name = NULL;
    msg.msg_namelen = 0;
    int tmp;
    iov.iov_base = &tmp;
    iov.iov_len = sizeof(int);
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;
    union {
        cmsghdr cm;
        char control[CMSG_SPACE(sizeof(int))];
    } control_un;
    msg.msg_control = control_un.control;
    msg.msg_controllen = sizeof(control_un.control);
    if (recvmsg(connfd, &msg, 0) < 0)
    {
        perror("recvmsg");
    }
    int recvfd = -1;
    auto cmptr = CMSG_FIRSTHDR(&msg);
    if (cmptr == NULL)
    {
        perror("CMSG");
    }
    if (cmptr->cmsg_type != SCM_RIGHTS)
    {
        perror("type");
    }
    recvfd = *((int *)CMSG_DATA(cmptr));
    char buf[] = "hello";
    printf("the fd: %d  ", recvfd);
    Write(recvfd, buf, strlen(buf) + 1);
    exit(0);
}
extern "C"
{
#include <unp.h>
}

int main(int argc, char **argv)
{
    int sndfd = open(argv[1], O_RDWR | O_TRUNC | O_CREAT);
    printf("the fd: %d", sndfd);
    sockaddr_un seraddr;
    bzero(&seraddr, sizeof(seraddr));
    seraddr.sun_family = AF_UNIX;
    strcpy(seraddr.sun_path, UNIXSTR_PATH);
    int connfd = Socket(AF_UNIX, SOCK_STREAM, 0);
    Connect(connfd, (SA *)&seraddr, sizeof(seraddr));
    msghdr msg;
    msg.msg_name = NULL;
    msg.msg_namelen = 0;
    iovec iov;
    iov.iov_base = &sndfd;
    iov.iov_len = sizeof(sndfd);
    msg.msg_flags = 0;
    union {
        cmsghdr cm;
        char pad[CMSG_SPACE(sizeof(int))];
    } control;
    msg.msg_control = control.pad;
    msg.msg_controllen = sizeof(control.pad);
    msg.msg_flags = 0;
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;
    auto cmsgptr = CMSG_FIRSTHDR(&msg);
    cmsgptr->cmsg_len = CMSG_LEN(sizeof(int));
    cmsgptr->cmsg_level = SOL_SOCKET;
    cmsgptr->cmsg_type = SCM_RIGHTS;
    *(int *)CMSG_DATA(cmsgptr) = sndfd;
    sendmsg(connfd, &msg, 0);
    exit(0);
}

免责声明:文章转载自《进程间传递文件描述符的方法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Kaggle大数据竞赛平台入门J2ee高并发情况下监听器下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Linux网络编程笔记(修订版)

我的网络编程笔记, 因为最近又要做Linux下的网络编程,故重新修订, 其中一些内容参考了文末的链接及文章 1.   基本概念 2.   基本接口 2.1.   打开一个socket 2.2.   将socket绑定定指定的端口—bind 2.3.   侦听socket—listen (服务器端) 2.4.   等待接收请求—accept (服务器端) 2...

Java虚拟机14:Java对象大小、对象内存布局及锁状态变化

一个对象占多少字节? 关于对象的大小,对于C/C++来说,都是有sizeof函数可以直接获取的,但是Java似乎没有这样的方法。不过还好,在JDK1.5之后引入了Instrumentation类,这个类提供了计算对象内存占用量的方法。至于具体Instrumentation类怎么用就不说了,可以参看这篇文章如何精确地测量java对象的大小。 不过有一点不同的...

三、五种IO模型透彻分析

三、五种IO模型透彻分析原文转载:https://www.cnblogs.com/f-ck-need-u/p/7624733.html 1、基础 在引入IO模型前,先对io等待时某一段数据的"经历"做一番解释。如图: 当某个程序或已存在的进程/线程(后文将不加区分的只认为是进程)需要某段数据时,它只能在用户空间中属于它自己的内存中访问、修改,这段内存暂且...

Linux内核结构体--kfifo 环状缓冲区

转载链接:http://blog.csdn.net/yusiguyuan/article/details/41985907 1、前言   最近项目中用到一个环形缓冲区(ring buffer),代码是由Linux内核的kfifo改过来的。缓冲区在文件系统中经常用到,通过缓冲区缓解cpu读写内存和读写磁盘的速度。例如一个进程A产生数据发给另外一个进程B,进程...

【网络开发】多播参数设置

原文:http://blog.chinaunix.NET/uid-28458801-id-5085099.html 11.3  多播 单播用于两个主机之间的端对端通信,广播用于一个主机对整个局域网上所有主机上的数据通信。单播和广播是两个极端,要么对一个主机进行通信,要么对整个局域网上的主机进行通信。实际情况下,经常需要对一组特定的主机进行通信,...

open与fopen 文件描述符与文件指针

首先说一下文件描述符与文件指针区别: 文件描述符:在linux系统中打开文件就会获得文件描述符,它是个很小的正整数。每个进程在PCB(Process Control Block)中保存着一份文件描述符表,文件描述符就是这个表的索引,每个表项都有一个指向已打开文件的指针。 文件指针:C语言中使用文件指针做为I/O的句柄。文件指针指向进程用户区中的一个被称为...