Chinaunix首页 | 论坛 | 博客
  • 博客访问: 387034
  • 博文数量: 39
  • 博客积分: 1982
  • 博客等级: 上尉
  • 技术积分: 468
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-07 13:47
文章分类

全部博文(39)

文章存档

2012年(5)

2011年(16)

2010年(18)

分类: C/C++

2011-02-25 11:54:34

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>

  4. #include <unistd.h>
  5. #include <sys/wait.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <fcntl.h>
  9. #include <errno.h>

  10. #include <sys/socket.h> /* for socketpair */

  11. #define MY_LOGO "Micheal"

  12. /*
  13. * 从fd中接收消息,并将文件描述符放在指针recvfd中
  14. */
  15. ssize_t recv_fd(int fd, void*data, size_t bytes, int*recvfd)
  16. {
  17.   struct msghdr msghdr_recv; /*接收消息接收*/
  18.   struct iovec iov[1]; /*接收数据的向量*/
  19.   size_t n;
  20.   int newfd;

  21.   union{
  22.     struct cmsghdr cm;
  23.     char control[CMSG_SPACE(sizeof(int))];
  24.   }control_un;
  25.   struct cmsghdr*pcmsghdr; /*消息头部*/
  26.   msghdr_recv.msg_control = control_un.control; /*控制消息*/
  27.   msghdr_recv.msg_controllen = sizeof(control_un.control); /*控制消息的长度*/

  28.   msghdr_recv.msg_name = NULL; /*消息的名称为空*/
  29.   msghdr_recv.msg_namelen = 0; /*消息的长度为空*/

  30.   iov[0].iov_base = data; /*向量的数据为传入的数据*/
  31.   iov[0].iov_len = bytes; /*向量的长度为传入数据的长度*/
  32.   msghdr_recv.msg_iov = iov; /*消息向量指针*/
  33.   msghdr_recv.msg_iovlen = 1; /*消息向量的个数为1个*/
  34.   if((n = recvmsg(fd, &msghdr_recv, 0))<=0) /*接收消息*/
  35.     return n;

  36.   if((pcmsghdr = CMSG_FIRSTHDR(&msghdr_recv))!= NULL && /*获得消息的头部*/
  37.       pcmsghdr->cmsg_len == CMSG_LEN(sizeof(int))) { /*获得消息的长度为int*/
  38.     if(pcmsghdr->cmsg_level != SOL_SOCKET) /*消息的level应该为SOL_SOCKET*/
  39.       printf("control level != SOL_SOCKET\n");

  40.     if(pcmsghdr->cmsg_type != SCM_RIGHTS) /*消息的类型判断*/
  41.       printf("control type != SCM_RIGHTS\n");

  42.     *recvfd =*((int*)CMSG_DATA(pcmsghdr)); /*获得打开文件的描述符*/
  43.   } else
  44.     *recvfd = -1;

  45.   return n; /*返回接收消息的长度*/
  46. }


  47. ssize_t send_fd(int fd, void*data, size_t bytes, int sendfd)
  48. {
  49.   struct msghdr msghdr_send; /*发送消息*/
  50.   struct iovec iov[1]; /*向量*/
  51.   size_t n; /*大小*/
  52.   int newfd; /*文件描述符*/
  53.   /*方便操作msg的结构*/
  54.   union{
  55.     struct cmsghdr cm; /*control msg结构*/
  56.     char control[CMSG_SPACE(sizeof(int))]; /*字符指针,方便控制*/
  57.   }control_un;
  58.   struct cmsghdr*pcmsghdr=NULL; /*控制头部的指针*/
  59.   msghdr_send.msg_control = control_un.control; /*控制消息*/
  60.   msghdr_send.msg_controllen = sizeof(control_un.control); /*长度*/

  61.   pcmsghdr = CMSG_FIRSTHDR(&msghdr_send); /*取得第一个消息头*/
  62.   pcmsghdr->cmsg_len = CMSG_LEN(sizeof(int)); /*获得长度*/
  63.   pcmsghdr->cmsg_level = SOL_SOCKET; /*用于控制消息*/
  64.   pcmsghdr->cmsg_type = SCM_RIGHTS;
  65.   *((int*)CMSG_DATA(pcmsghdr))= sendfd; /*socket值*/


  66.   msghdr_send.msg_name = NULL; /*名称*/
  67.   msghdr_send.msg_namelen = 0; /*名称长度*/

  68.   iov[0].iov_base = data; /*向量指针*/
  69.   iov[0].iov_len = bytes; /*数据长度*/
  70.   msghdr_send.msg_iov = iov; /*填充消息*/
  71.   msghdr_send.msg_iovlen = 1;

  72.   return (sendmsg(fd, &msghdr_send, 0)); /*发送消息*/
  73. }


  74. int main()
  75. {
  76.   pid_t pid;
  77.   int sockpair[2];
  78.   int rv;
  79.   char fname[256];
  80.   int fd;
  81.   char rev,sen;

  82.   rv = socketpair(AF_UNIX, SOCK_STREAM, 0, sockpair);
  83.   if (rv < 0) {
  84.     printf("Call socketpair error, errno is %d\n", errno);
  85.     return errno;
  86.   }

  87.   pid = fork();
  88.   if (pid == 0) {
  89.     /* in child */
  90.     close(sockpair[1]);

  91.     for ( ; ; ) {
  92.       //fd = recv_fd(sockpair[0]);

  93.       recv_fd(sockpair[0],&rev,1,&fd);

  94.       if (fd < 0) {
  95.         printf("[CHILD]: child process exit normally!\n");
  96.         break;
  97.       }

  98.       /* 处理fd描述符对应的文件 */
  99.       rv = write(fd, MY_LOGO, strlen(MY_LOGO));
  100.       if (rv < 0) {
  101.         printf("[CHILD]: write error, errno is %d\n", rv);
  102.       } else {
  103.         printf("[CHILD]: append logo successfully\n");
  104.       }
  105.       close(fd);
  106.     }
  107.     exit(0);
  108.   }
  109.   /* in parent */
  110.   for ( ; ; ) {
  111.     memset(fname, 0, sizeof(fname));
  112.     printf("[PARENT]: please enter filename:\n");
  113.     scanf("%s", fname);

  114.     // if (strcmp(fname, "exit") == 0) {

  115.     // rv = send_fd(sockpair[1], -1);

  116.     // if (rv < 0) {

  117.     // printf("[PARENT]: send_fd error, errno is %d\n", rv);

  118.     // }

  119.     // break;

  120.     // }


  121.     fd = open(fname, O_RDWR | O_APPEND);
  122.     if (fd < 0) {
  123.       if (errno == ENOENT) {
  124.         printf("[PARENT]: can't find file '%s'\n", fname);
  125.         continue;
  126.       }
  127.       printf("[PARENT]: open file error, errno is %d\n", errno);
  128.     }
  129.     //rv = send_fd(sockpair[1], fd);

  130.     send_fd(sockpair[1],"",1,fd);
  131.     if (rv != 0) {
  132.       printf("[PARENT]: send_fd error, errno is %d\n", rv);
  133.     }
  134.     //close(fd);

  135.     rv = write(fd, "PARENT write\n", strlen("PARENT write\n"));
  136.     if (rv < 0) {
  137.       printf("[PARENT]: write error, errno is %d\n", rv);
  138.     } else {
  139.       printf("[PARENT]: append logo successfully\n");
  140.     }
  141.   }
  142.   wait(NULL);
  143.   return 0;
  144. }
阅读(2224) | 评论(0) | 转发(0) |
0

上一篇:发送文件描述符函数

下一篇:C语言笔记本

给主人留下些什么吧!~~