0707 父子进程之间传递文件描述符

  1 /*************************************************************************
  2     > File Name: pass_fd.c
  3     > Author:Monica
  4     > Mail:[email protected]
  5     > Created Time: Mon 07 Jul 2014 09:52:49 PM CST
  6  ************************************************************************/
  7
  8 #include <stdio.h>
  9 #include <sys/types.h>
 10 #include <sys/socket.h>
 11 #include <strings.h>
 12 #include <stdlib.h>
 13 #include <unistd.h>
 14 #include <signal.h>
 15 #include <sys/stat.h>
 16 #include <fcntl.h>
 17 #include <string.h>
 18
 19 void my_handler(int signum)
 20 {
 21     wait(NULL);
 22     exit(0);
 23 }
 24 void send_n(int fd_socket, int fd_to_send);
 25 void recv_n(int fd_socket, int* fd_to_recv);
 26
 27 int main(int argc, char* argv[])    //exe  filename
 28 {
 29     int fd_socket[2];
 30     int fd_file;
 31     if(socketpair(AF_LOCAL, SOCK_STREAM, 0, fd_socket) == -1)
 32     {
 33         perror("socketpair");
 34         exit(-1);
 35     }
 36     if(fork()>0)    //parent fd[0]
 37     {
 38         close(fd_socket[1]);
 39         signal(SIGCHLD, my_handler);
 40         fd_file = open(argv[1], O_RDONLY);
 41         if(fd_file == -1)
 42         {
 43             perror("open");
 44             close(fd_socket[0]);
 45             close(fd_socket[1]);
 46             exit(-1);
 47         }
 48         send_n(fd_socket[0], fd_file);
 49         printf("parent fd_file:%d\n", fd_file);
 50         close(fd_file);
 51         close(fd_socket[0]);
 52         return;
 53     }
 54     else    //child fd[1]
 55     {
 56         int fd_to_recv;
 57         char buf[1024];
 58         close(fd_socket[0]);
 59         recv_n(fd_socket[1], &fd_to_recv);
 60         printf("child recv fd:%d\n", fd_to_recv);
 61         FILE* fp = fdopen(fd_to_recv, "r");
 62         while(bzero(buf, 1024), fgets(buf, 1024, fp) != NULL)
 63         {
 64             printf("%s", buf);
 65         }
 66         fclose(fp);
 67         close(fd_to_recv);
 68         close(fd_socket[1]);
 69     }
 70     return 0;
 71 }
 72 void send_n(int fd_socket, int fd_to_send)
 73 {
 74     struct msghdr send_msg;
 75     struct iovec  bufs[1];
 76     struct cmsghdr *pcmsg;
 77     char buffer[]="hello world";
 78     int cmsglen = CMSG_LEN(sizeof(int));
 79     send_msg.msg_name = NULL;
 80     send_msg.msg_namelen = 0;
 81     send_msg.msg_flags = 0;
 82     bufs[0].iov_base = buffer;
 83     bufs[0].iov_len = strlen(buffer);
 84     send_msg.msg_iov = bufs;
 85     send_msg.msg_iovlen = 1;
 86     pcmsg = (struct cmsghdr*)calloc(1, cmsglen);
 87     pcmsg->cmsg_len = cmsglen;
 88     pcmsg->cmsg_level = SOL_SOCKET;
 89     pcmsg->cmsg_type = SCM_RIGHTS;
 90     *(int*)CMSG_DATA(pcmsg) = fd_to_send;
 91     send_msg.msg_control = pcmsg;
 92     send_msg.msg_controllen = cmsglen;
 93     sendmsg(fd_socket, &send_msg, 0);
 94 }
 95
 96 void recv_n(int fd_socket, int* fd_to_recv)
 97 {
 98     struct msghdr recv_msg;
 99     struct iovec  bufs[1];
100     struct cmsghdr*  pcmsg;
101     char buffer[1024]="";
102     int cmsglen = CMSG_LEN(sizeof(int));
103     pcmsg = (struct cmsghdr*)calloc(1,cmsglen );
104     bufs[0].iov_base = buffer;
105     bufs[0].iov_len = 1024;
106     recv_msg.msg_iov = bufs;
107     recv_msg.msg_iovlen = 1;
108     recv_msg.msg_control = pcmsg;
109     recv_msg.msg_controllen = cmsglen;
110     recvmsg(fd_socket, &recv_msg, 0);
111     printf("buf:%s\n", buffer);
112     *fd_to_recv = *(int*)CMSG_DATA(pcmsg);
113 }

0707 父子进程之间传递文件描述符,布布扣,bubuko.com

时间: 2024-10-13 23:26:42

0707 父子进程之间传递文件描述符的相关文章

UNIX进程之间传递文件描述符recvmsg与sendmsg

socketpair: 功能:创建一个全双工的流管道 原型 int socketpair(int domain, int type, int protocol, int sv[2]); 参数 domain: 协议家族 type: 套接字类型 protocol: 协议类型 sv: 返回套接字对 返回值:成功返回0:失败返回-1 ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags); ssize_t recvmsg(int

C/C++ 父子进程之间的文件描述符问题

在C程序中,文件由文件指针或者文件描述符表示.ISO C的标准I/0库函数(fopen, fclose, fread, fwrite, fscanf, fprintf等)使用文件指针,UNIX的I/O函数(open, close, read, write, ioctl)使用文件描述符.下面重点来说下,文件描述符是如何工作的. 文件描述符相当于一个逻辑句柄,而open,close等函数则是将文件或者物理设备与句柄相关联.句柄是一个整数,可以理解为进程特定的文件描述符表的 索引.先介绍下面三个概念,

进程间传递文件描述符

下面的实例展示了如何使用Unix域套接字在进程间传递文件描述符 参考文献:1) <Unix网络编程> 2)  http://book.51cto.com/art/200912/168560.htm 最近学习了使用Unix域套接字在进程间传递文件描述符,仿照参考资料,自己也写了简单的程序来实践这种技术. 其他不多说了,具体理论知识参见参考资料,开始我自己的程序介绍(在OpenSolaris 2009.06平台上测试): 1  程序作用说明:父进程,子进程以及另外一个进程向同一个文件的文件描述符向

进程间传递文件描述符——sendmsg和recvmsg函数

先引入一个例子,该程序的目的是子进程向父进程传递文件描述符,并通过该文件描述符读取buf. #include <func.h> int main(){ int fds[2]; pipe(fds); if(!fork()){ close(fds[1]); int fd; read(fds[0], &fd, sizeof(fd)); printf("child fd = %d\n", fd); char buf[128] = {0}; read(fd, buf, siz

在进程间传递文件描述符

由于fork调用之后,父进程中打开的文件描述符在子进程中仍然保持打开,所以文件描述符可以很方便地从父进程传递到子进程.需要注意的是,传递一个文件描述符并不是传递一个文件描述符的值,而是要在接收进程中创建一个新的文件描述符,并且该文件描述符和发送进程中被传递的文件描述符指向内核中相同的文件表项. 在Linux下,我们可以利用UNIX城socket在进程间传递特殊的辅助数据,以实现文件描述符的传递,它在子进程中打开一个文件描述符,然后将它传递给父进程,父进程则通过读取该文件描述符来获得文件的内容.

python进程间传递文件描述符扩展库

由于python本身的线程基本上比较残废,所以为了利用机器的cpu,就不得不用上多进程... 在游戏服务器的设计中,最为常见的方式是: 挂一个前端服务器,专门来维护与客户端的连接,然后将客户端的请求数据转发给后端服务器... 上面的方式是现在最为正统的... 但是自己因为环境的限制,需要做到对客户端透明,然后将后端的服务器转换成为多进程的...所以这里就只有用一点比较别扭的方法了,首先处理登录等一些常规的逻辑放在前端服务器,当进入放进进行匹配战斗之后,将客户端的socket连接直接交给后端服务器

通过UNIX域套接字传递文件描述符

传送文件描述符是高并发网络服务编程的一种常见实现方式.Nebula 高性能通用网络框架即采用了UNIX域套接字传递文件描述符设计和实现.本文详细说明一下传送文件描述符的应用. 1. TCP服务器程序设计范式 ??开发一个服务器程序,有较多的的程序设计范式可供选择,不同范式有其自身的特点和实用范围,明了不同范式的特性有助于我们服务器程序的开发.常见的TCP服务器程序设计范式有以下几种: 迭代服务器 并发服务器,每个客户请求fork一个子进程 预先派生子进程,每个子进程无保护地调用accept 预先

在父子进程间用管道传递文件描述符

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <sys/socket.h> #define ERR_EXI

服务器编程中的文件描述符

linux系统下一切皆文件,通过虚拟文件系统(VFS)的机制将所有底层屏蔽掉,用户可以通过统一的接口来实现对不同驱动的操作,对于每一个文件需要一个引用来指示,此时文件描述符应用而生,文件描述符类似于widows下的handle,对于文件的大部分操作都是通过这个描述符来操作的,例如read,write.对于每一个文件描述符,内核使用三种数据结构来管理. (1)  每个进程在进程表中都有一个记录项,每个记录项中有一张打开文件描述符表,可将其视为一个矢量,每个描述符占用一项.与每个文件描述符相关联的是