标题: 我的子进程如何退出才正确??
nils
新生入学
Rank: 1



UID 197408
精华 0
积分 10(积分有什么用?)
帖子 3
阅读权限 10
注册 2007-6-6
状态 离线
发表于 2007-6-11 16:23  资料  个人空间  短消息  加为好友 
我的子进程如何退出才正确??

小弟编写了一个TCP的服务器客户端相互发送信息的程序,代码如下。程序可以运行的,可是现在的问题是:我fork出的子进程没有正确退出??
`:G5WJ1`&Y-D!Vt环境如下: 现运行./server 然后运行./client,在client运行期间用ps -ef | grep server 观看进程信息,有2个进程,等到程序结束后再用同样的命令看,有一个变成了僵尸??但是你再运行一次client的时候僵尸不见了 ,还是2个进程,为什么? 那个不是僵尸??
RD8Tt0_?8hq

nils@linux-scj:~> ps -ef | grep server   //第一次运行时的结果A!U b.]"Lmh
nils     19325 18236  0 16:14 pts/2    00:00:00 ./server
L3xsN1X`nils     19327 19325  0 16:14 pts/2    00:00:00 ./server
Qg_f}zWnils     19329 18761  0 16:14 pts/4    00:00:00 grep server
8i?#}4z/YJ$?WsO
E
nils@linux-scj:~> ps -ef | grep server           //运行结束后的结果
!D${n!W5Dwww.linuxeden.comnils     19325 18236  0 16:14 pts/2    00:00:00 ./servert8hQn
@q

nils     19327 19325  0 16:14 pts/2    00:00:00 [server] <defunct>Linux伊甸园论坛sWRzH/_
nils     19335 18761  0 16:14 pts/4    00:00:00 grep server
SG)Z2ZiA4`yp
wwww.linuxeden.com
nils@linux-scj:~> ps -ef | grep server        ySx(h
uJr3G&\

nils     19325 18236  0 16:14 pts/2    00:00:00 ./server
^1N5E]Trnils     19360 19325  0 16:17 pts/2    00:00:00 ./serverwww.linuxeden.com'@
k.f pb:ms:@@

nils     19362 18761  0 16:17 pts/4    00:00:00 grep server
`%LXc'U.PbLinux伊甸园论坛
CI#T0S&D&f{不知道问题出在哪里,求助!

/*
server.c  要求实现的功能:
*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>

#define PORT 4444
#define BACKLOG 10
#define MAXDATASIZE 4096

int main()
{
        int        listen_fd,new_fd;
        fd_set        readfds,writefds;
        int        ret;
        char        buf[MAXDATASIZE];
        int        sin_size;
        int        numbytes;
        struct         sockaddr_in their_addr;
        struct         sockaddr_in my_addr;
               
        FD_ZERO(&readfds);
        FD_ZERO(&writefds);
       
        if ((listen_fd = socket(AF_INET,SOCK_STREAM,0)) == -1)
        {
                perror("socket");
                exit(1);
        }
       
        my_addr.sin_family = AF_INET;
        my_addr.sin_port = htons(PORT);
        my_addr.sin_addr.s_addr = INADDR_ANY;
        bzero(&(my_addr.sin_zero),8);
               
        if(bind(listen_fd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr)) == -1)
        {
                perror("bind");
                exit(1);               
        }

        if (listen(listen_fd,BACKLOG) == -1)
        {
                       
        }
       
        FD_SET(listen_fd,&readfds);
        for(;;)
        {
                ret = select(listen_fd+1,&readfds,NULL,NULL,NULL);
                if(FD_ISSET(listen_fd,&readfds))
                {
                        sin_size =sizeof(struct sockaddr_in);
                        if((new_fd = accept(listen_fd,(struct sockaddr*)&their_addr,&sin_size)) == -1)
                        {
                                perror("accept");
                                continue;                               
                        }
                        printf("server: got connection from %s\n",inet_ntoa(their_addr.sin_addr));
                       
                        if (!fork())
                        {
                                //先发送一个信息给客户端
                                if(send(new_fd,"Hello world\n",14,0) == -1)
                                {
                                        perror("send");
                                        close(new_fd);
                                        exit(0);//这里在子进程里 不能用continue;       
                                }
                                FD_SET(new_fd,&readfds);
                                //FD_SET(new_fd,&writefds);
                                for(;;)
                                {
                                        ret = select((listen_fd>new_fd?listen_fd+1:new_fd+1),&readfds,NULL,NULL,NULL);
                                        if(FD_ISSET(new_fd,&readfds))
                                        {
                                                if((numbytes=recv(new_fd,buf,MAXDATASIZE,0)) == -1)
                                                {
                                                        perror("send");
                                                        close(new_fd);
                                                        exit(0);//这里在子进程里 不能用continue;                       
                                                }
                                                if (numbytes > 0)
                                                {
                                                        buf[numbytes] = '\0';
                                                        printf("Recv: %d\t%s",numbytes,buf);
                                                }
                               
                                               
                                                //这里可以使用一个特定的消息作为结束
                                                if (strcmp(buf,"quit\n") == 0)
                                                {
                                                        printf("QUIT recved!\n");
                                                        FD_CLR(new_fd,&readfds);
                                                        close(new_fd);
                                                        //exit(0);        这里如果用exit那么就会产生僵尸???
                                                        return 0;
                                                        //break;
                                                }
                                                //再向客户端发送一条信息
                                                if (send(new_fd,"A new string\n",14,0) == -1)
                                                {
                                                        perror("send");
                                                        close(new_fd);
                                                        exit(0);//这里在子进程里 不能用continue
                                                }
                                                else
                                                        printf("Msg Send!\n");
                                        }                               
                                }
                        }
                }
                //等待所有子进程退出
                while(waitpid(-1,NULL,WNOHANG)>0);
                printf("Father Flushed!\n");
                //return 0;
        }
        return 0;
}


/*
client.c  要求实现的功能:每秒向server发送一个消息
*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>

#define PORT 4444
#define BACKLOG 10
#define MAXDATASIZE 4096

int main()
{
        int        sock_fd,numbytes;
        char         buf[MAXDATASIZE];
        struct         hostent *he;
        struct sockaddr_in their_addr;
        int         ret;
        fd_set  readfds;
        int        cnt = 0;
        char* strIP="20.0.0.5";

        FD_ZERO(&readfds);
       
        if ((he = gethostbyname(strIP)) == NULL)
        {
                perror("gethostbyname");
                exit(1);
        }
       
        if ((sock_fd=socket(AF_INET,SOCK_STREAM,0)) == -1)
        {
                perror("socket");
                exit(1);                       
        }
       
        their_addr.sin_family =AF_INET;
        their_addr.sin_port =htons(PORT);
        their_addr.sin_addr = *((struct in_addr*)he->h_addr);
        bzero(&(their_addr.sin_zero),8);
       
        if (connect(sock_fd,(struct sockaddr*)&their_addr,sizeof(struct sockaddr)) == -1)
        {
                perror("connect");
                exit(1);
        }
       
        if ((numbytes = recv(sock_fd,buf,MAXDATASIZE,0)) == -1)
        {
                perror("recv");
                exit(1);       
        }
        if(numbytes > 0)
        {
                buf[numbytes] = '\0';
                printf("Recv:%s",buf);
        }
       
        while(cnt++ < 10)
        {
                sleep(1);
                if(send(sock_fd,"subsentence\n",13,0) == -1)
                {
                        perror("send");
                        close(sock_fd);
                        exit(0);//这里在子进程里 不能用continue;       
                }
                FD_SET(sock_fd,&readfds);
                ret = select(sock_fd+1,&readfds,NULL,NULL,NULL);
                if(FD_ISSET(sock_fd,&readfds))
                {
                        if ((numbytes = recv(sock_fd,buf,MAXDATASIZE,0)) == -1)
                        {
                                perror("recv");
                                exit(1);       
                        }
                        if(numbytes > 0)
                        {
                                buf[numbytes] = '\0';
                                printf("Recv:%s",buf);
                        }
                }
        }
       
        if(send(sock_fd,"quit\n",5,0) == -1)
        {
                perror("send");
                close(sock_fd);
                exit(0);//这里在子进程里 不能用continue;       
        }
        close(sock_fd);
       
        return 0;
}


顶部
flag
版主
Rank: 7Rank: 7Rank: 7
版主



UID 19801
精华 1
积分 28(积分有什么用?)
帖子 5581
阅读权限 100
注册 2002-7-19
状态 在线
发表于 2007-6-12 11:54  资料  个人空间  短消息  加为好友 
//等待所有子进程退出
%O-[1n-fN                while(waitpid(-1,NULL,WNOHANG)>0);Linux伊甸园论坛3cPLok%e'Rb
                printf("Father Flushed!\n");Linux伊甸园论坛6Yb;h-Y$B(D$A9A        C
man过waitpid吗?5bOa{7[&b:S4B
WNOHANGLinux伊甸园论坛-|(U.] ]6|
              which means to return immediately if no child has exited.





上帝说,有问题,找GOOGLE 写程序是很神圣的事情!同样只是装系统,卖菜的大娘会的事情不见得就跟卖菜一样了。
顶部
 



当前时区 GMT+8, 现在时间是 2008-5-17 10:40

    Powered by Discuz! 5.5.0  © 2001-2007 Comsenz Inc.
Processed in 0.095695 second(s), 5 queries

清除 Cookies - 联系我们 - Linux伊甸园 - Archiver - WAP