1

我试图让我的 server.c 程序能够处理僵尸进程。最初,我signal(SIGCHLD,SIG_IGN);linuxhowtos.org/C_C++/socket找到了这一行。这就像一个魅力。我可以与客户端连接,然后关闭客户端,一切仍然运行顺利。

但是,我正在尝试用文章中所写的 SigCatcher 替换 SIG_IGN,并且当客户端关闭时,我的服务器程序开始出现问题(它无限地继续接收“2”并输出它)。

我都试过了wait3(NULL,WNOHANG,NULL)wait(-1)但这些都没有解决问题。我到底应该在这里做什么?

void *SignalCatcher(int n)
{
  wait3(NULL,WNOHANG,NULL);
}

这是我的主要外观:

   //signal(SIGCHLD, SIG_IGN);
   signal(SIGCHLD, SignalCatcher);

   for(;;)
   {
      clilen=sizeof(cliaddr);
      connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&clilen);


      if ((childpid = fork()) == 0)
      {
         close (listenfd);

         for(;;)
         {
            n = recvfrom(connfd,mesg,1000,0,(struct sockaddr*)&cliaddr,&clilen);
            write(connfd , "" , 1);
            mesg[n] = 0;
            printf("Received the following:\n");
            printf("%s",mesg);

         }

      }
      close(connfd);
   }
4

2 回答 2

1
void *SignalCatcher(int n)
{
  wait3(NULL,WNOHANG,NULL);
}

应该:

void SignalCatcher(int signum)
{
  wait3(NULL,WNOHANG,NULL);
}

返回类型在信号处理程序中非常关键(因为调用约定与普通函数调用不同)。无论如何,编译器至少应该发出警告。

第二:在循环中,您应该处理来自 recvfrom() 的错误返回。(和写() )

for(;;) {
        n = recvfrom(connfd,mesg,1000,0,(struct sockaddr*)&cliaddr,&clilen);
        if (n == -1 && errno = EAGAIN) continue;
        else if (n == 0) break; // for non-blocking sockets...
        write(connfd , "" , 1);
        mesg[n] = 0;
        printf("Received the following: %s\n", mesg);
     }
于 2013-02-27T22:23:01.670 回答
0

何必那么辛苦呢?只需在孩子一开始就将其守护进程(例如,fork 两次,第一个孩子立即退出,而孙子继续以 pid 1 作为其父进程。)除非有理由保持工作进程的父进程,否则这将大大简化了事情。

于 2013-02-27T13:32:05.560 回答