免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4032 | 回复: 12
打印 上一主题 下一主题

[Linux] 询问父进程传递一个sockfd给子进程的问题 :Bad file descriptor [复制链接]

论坛徽章:
4
亥猪
日期:2013-09-27 13:50:29酉鸡
日期:2013-10-09 13:08:59丑牛
日期:2013-10-20 11:16:47亥猪
日期:2013-10-26 11:50:59
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-11-07 20:29 |只看该作者 |倒序浏览
rt, 父进程 创建子进程池, 然后父进程accept一个newconnfd,然后使用pipe传给子进程, 子进程无法对这个newconnfd 进行recv也无法send, 总是报Bad file descriptor...
我把这个newconnfd的值在父进程accept的时候打印了出来, 在子进程从pipe里面读出来的时候也打印了一下,发现他们的值是一样的...
(ps:查看了下unpv2的一个例子,他是用msg来传递的...难道是不能这样用pipe传递使用么? 求高人指点下啊 )

论坛徽章:
4
亥猪
日期:2013-09-27 13:50:29酉鸡
日期:2013-10-09 13:08:59丑牛
日期:2013-10-20 11:16:47亥猪
日期:2013-10-26 11:50:59
2 [报告]
发表于 2013-11-07 20:31 |只看该作者
再加一句, 所有的recv和send 代码移动到父进程中就正确了回复 1# AssassinPig


   

论坛徽章:
4
亥猪
日期:2013-09-27 13:50:29酉鸡
日期:2013-10-09 13:08:59丑牛
日期:2013-10-20 11:16:47亥猪
日期:2013-10-26 11:50:59
3 [报告]
发表于 2013-11-07 20:31 |只看该作者
再加一句, 所有的recv和send 代码移动到父进程中就正确了回复 1# AssassinPig


   

论坛徽章:
16
CU十二周年纪念徽章
日期:2013-10-24 15:41:3415-16赛季CBA联赛之广东
日期:2015-12-23 21:21:55青铜圣斗士
日期:2015-12-05 10:35:30黄金圣斗士
日期:2015-11-26 20:42:16神斗士
日期:2015-11-19 12:47:50每日论坛发贴之星
日期:2015-11-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-18 06:20:002015亚冠之城南
日期:2015-11-10 19:10:492015亚冠之萨济拖拉机
日期:2015-10-28 18:47:282015亚冠之柏太阳神
日期:2015-08-30 17:21:492015亚冠之山东鲁能
日期:2015-07-07 18:48:39摩羯座
日期:2014-08-29 23:01:42
4 [报告]
发表于 2013-11-07 20:39 |只看该作者
回复 3# AssassinPig


    因为你的子进程并没有继承父进程的fd。原因就是你先创建子进程池的时候,,那哈还没有accept,,所以就不能继承了

论坛徽章:
4
亥猪
日期:2013-09-27 13:50:29酉鸡
日期:2013-10-09 13:08:59丑牛
日期:2013-10-20 11:16:47亥猪
日期:2013-10-26 11:50:59
5 [报告]
发表于 2013-11-07 20:59 |只看该作者
我也想过是这个原因,但是我参考的代码就是在这么干的...所以我很迷惑啊...回复 4# tc1989tc


   

论坛徽章:
16
CU十二周年纪念徽章
日期:2013-10-24 15:41:3415-16赛季CBA联赛之广东
日期:2015-12-23 21:21:55青铜圣斗士
日期:2015-12-05 10:35:30黄金圣斗士
日期:2015-11-26 20:42:16神斗士
日期:2015-11-19 12:47:50每日论坛发贴之星
日期:2015-11-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-18 06:20:002015亚冠之城南
日期:2015-11-10 19:10:492015亚冠之萨济拖拉机
日期:2015-10-28 18:47:282015亚冠之柏太阳神
日期:2015-08-30 17:21:492015亚冠之山东鲁能
日期:2015-07-07 18:48:39摩羯座
日期:2014-08-29 23:01:42
6 [报告]
发表于 2013-11-07 21:54 |只看该作者
把你参考的代码贴出来

论坛徽章:
4
亥猪
日期:2013-09-27 13:50:29酉鸡
日期:2013-10-09 13:08:59丑牛
日期:2013-10-20 11:16:47亥猪
日期:2013-10-26 11:50:59
7 [报告]
发表于 2013-11-07 23:05 |只看该作者
  1. /* include serv05a */
  2. #include        "unp.h"
  3. #include        "child.h"

  4. static int                nchildren;

  5. int
  6. main(int argc, char **argv)
  7. {
  8.         int                        listenfd, i, navail, maxfd, nsel, connfd, rc;
  9.         void                sig_int(int);
  10.         pid_t                child_make(int, int, int);
  11.         ssize_t                n;
  12.         fd_set                rset, masterset;
  13.         socklen_t        addrlen, clilen;
  14.         struct sockaddr        *cliaddr;

  15.         if (argc == 3)
  16.                 listenfd = Tcp_listen(NULL, argv[1], &addrlen);
  17.         else if (argc == 4)
  18.                 listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
  19.         else
  20.                 err_quit("usage: serv05 [ <host> ] <port#> <#children>");

  21.         FD_ZERO(&masterset);
  22.         FD_SET(listenfd, &masterset);
  23.         maxfd = listenfd;
  24.         cliaddr = Malloc(addrlen);

  25.         nchildren = atoi(argv[argc-1]);
  26.         navail = nchildren;
  27.         cptr = Calloc(nchildren, sizeof(Child));

  28.                 /* 4prefork all the children */
  29.         for (i = 0; i < nchildren; i++) {
  30.                 child_make(i, listenfd, addrlen);        /* parent returns */
  31.                 FD_SET(cptr[i].child_pipefd, &masterset);
  32.                 maxfd = max(maxfd, cptr[i].child_pipefd);
  33.         }

  34.         Signal(SIGINT, sig_int);

  35.         for ( ; ; ) {
  36.                 rset = masterset;
  37.                 if (navail <= 0)
  38.                         FD_CLR(listenfd, &rset);        /* turn off if no available children */
  39.                 nsel = Select(maxfd + 1, &rset, NULL, NULL, NULL);

  40.                         /* 4check for new connections */
  41.                 if (FD_ISSET(listenfd, &rset)) {
  42.                         clilen = addrlen;
  43.                         connfd = Accept(listenfd, cliaddr, &clilen);

  44.                         for (i = 0; i < nchildren; i++)
  45.                                 if (cptr[i].child_status == 0)
  46.                                         break;                                /* available */

  47.                         if (i == nchildren)
  48.                                 err_quit("no available children");
  49.                         cptr[i].child_status = 1;        /* mark child as busy */
  50.                         cptr[i].child_count++;
  51.                         navail--;

  52.                         n = Write_fd(cptr[i].child_pipefd, "", 1, connfd);
  53.                         Close(connfd);
  54.                         if (--nsel == 0)
  55.                                 continue;        /* all done with select() results */
  56.                 }

  57.                         /* 4find any newly-available children */
  58.                 for (i = 0; i < nchildren; i++) {
  59.                         if (FD_ISSET(cptr[i].child_pipefd, &rset)) {
  60.                                 if ( (n = Read(cptr[i].child_pipefd, &rc, 1)) == 0)
  61.                                         err_quit("child %d terminated unexpectedly", i);
  62.                                 cptr[i].child_status = 0;
  63.                                 navail++;
  64.                                 if (--nsel == 0)
  65.                                         break;        /* all done with select() results */
  66.                         }
  67.                 }
  68.         }
  69. }
  70. /* end serv05a */

  71. void
  72. sig_int(int signo)
  73. {
  74.         int                i;
  75.         void        pr_cpu_time(void);

  76.                 /* 4terminate all children */
  77.         for (i = 0; i < nchildren; i++)
  78.                 kill(cptr[i].child_pid, SIGTERM);
  79.         while (wait(NULL) > 0)                /* wait for all children */
  80.                 ;
  81.         if (errno != ECHILD)
  82.                 err_sys("wait error");

  83.         pr_cpu_time();

  84.         for (i = 0; i < nchildren; i++)
  85.                 printf("child %d, %ld connections\n", i, cptr[i].child_count);

  86.         exit(0);
  87. }
复制代码

论坛徽章:
4
亥猪
日期:2013-09-27 13:50:29酉鸡
日期:2013-10-09 13:08:59丑牛
日期:2013-10-20 11:16:47亥猪
日期:2013-10-26 11:50:59
8 [报告]
发表于 2013-11-07 23:06 |只看该作者
  1. /* include child_make */
  2. #include        "unp.h"
  3. #include        "child.h"

  4. pid_t
  5. child_make(int i, int listenfd, int addrlen)
  6. {
  7.         int                sockfd[2];
  8.         pid_t        pid;
  9.         void        child_main(int, int, int);

  10.         Socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd);

  11.         if ( (pid = Fork()) > 0) {
  12.                 Close(sockfd[1]);
  13.                 cptr[i].child_pid = pid;
  14.                 cptr[i].child_pipefd = sockfd[0];
  15.                 cptr[i].child_status = 0;
  16.                 return(pid);                /* parent */
  17.         }

  18.         Dup2(sockfd[1], STDERR_FILENO);                /* child's stream pipe to parent */
  19.         Close(sockfd[0]);
  20.         Close(sockfd[1]);
  21.         Close(listenfd);                                        /* child does not need this open */
  22.         child_main(i, listenfd, addrlen);        /* never returns */
  23. }
  24. /* end child_make */

  25. /* include child_main */
  26. void
  27. child_main(int i, int listenfd, int addrlen)
  28. {
  29.         char                        c;
  30.         int                                connfd;
  31.         ssize_t                        n;
  32.         void                        web_child(int);

  33.         printf("child %ld starting\n", (long) getpid());
  34.         for ( ; ; ) {
  35.                 if ( (n = Read_fd(STDERR_FILENO, &c, 1, &connfd)) == 0)
  36.                         err_quit("read_fd returned 0");
  37.                 if (connfd < 0)
  38.                         err_quit("no descriptor from read_fd");

  39.                 web_child(connfd);                                /* process request */
  40.                 Close(connfd);

  41.                 Write(STDERR_FILENO, "", 1);        /* tell parent we're ready again */
  42.         }
  43. }
  44. /* end child_main */
复制代码

论坛徽章:
4
亥猪
日期:2013-09-27 13:50:29酉鸡
日期:2013-10-09 13:08:59丑牛
日期:2013-10-20 11:16:47亥猪
日期:2013-10-26 11:50:59
9 [报告]
发表于 2013-11-07 23:06 |只看该作者
  1. #include        "unp.h"

  2. #define        MAXN        16384                /* max # bytes client can request */

  3. void
  4. web_child(int sockfd)
  5. {
  6.         int                        ntowrite;
  7.         ssize_t                nread;
  8.         char                line[MAXLINE], result[MAXN];

  9.         for ( ; ; ) {
  10.                 if ( (nread = Readline(sockfd, line, MAXLINE)) == 0)
  11.                         return;                /* connection closed by other end */

  12.                         /* 4line from client specifies #bytes to write back */
  13.                 ntowrite = atol(line);
  14.                 if ((ntowrite <= 0) || (ntowrite > MAXN))
  15.                         err_quit("client request for %d bytes", ntowrite);

  16.                 Writen(sockfd, result, ntowrite);
  17.         }
  18. }
复制代码

论坛徽章:
4
亥猪
日期:2013-09-27 13:50:29酉鸡
日期:2013-10-09 13:08:59丑牛
日期:2013-10-20 11:16:47亥猪
日期:2013-10-26 11:50:59
10 [报告]
发表于 2013-11-07 23:07 |只看该作者
unp代码里面 server/serv05.c child05.c web_child.c
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP