UNIX网络编程5.10wait和waitpid函数

0DOMONJI({V196@[ZAA58GU

 

P[WLFS]7NU(KYYGF%5LX30A

 

PRGPEVTB4LYDU@UQ7G1SGYN

 

1S[1YINF$P6K87@EN{DL[C4

 

PHSM[J9Q18[A{856EVSCUQG

 

R[K](G%N4[)CO~2VX[`_YN0

 

#include <iostream>
#include "../lib/unpsunyj.h"

int main(int argc, char** argv)
{
    int                listenfd;
    int                connfd;
    pid_t              childpid;
    socklen_t          clilen;
    struct sockaddr_in cliaddr;
    struct sockaddr_in servaddr;

    // listenfd = Socket(AF_INET, SOCK_STREAM, 0);
    if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        err_sys("socket error");

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family      = AF_INET; // 如果是多宿,我们将接受目的地址为任何本地接口的连接
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    std::cout << SERV_PORT << std::endl;
    servaddr.sin_port        = htons(SERV_PORT);

    // Bind(listenfd, (SA*)&servaddr, sizeof(servaddr));
    if (bind(listenfd, (sockaddr*)&servaddr, sizeof(servaddr)) < 0)
    {
        err_sys("bind error");
    }

    // Listen(listenfd, LISTENQ); // 转换为监听套接字
    if (listen(listenfd, LISTENQ) < 0)
    {
        err_sys("listen error");
    }

    Signal(SIGCHLD, sig_chld);

    for ( ; ; )
    {
        clilen = sizeof(cliaddr);
        // connfd = Accept(listenfd, (SA *) &cliaddr, &len);
        if ((connfd = accept(listenfd, (sockaddr*)&cliaddr, &clilen)) < 0)
        {
            if (errno == EINTR)
            {
            	continue;
            }
            else
            {
                err_sys("accept error");
            }
        }

        // clilen = sizeof(cliaddr);
        // 服务器阻塞于accept调用,等待客户连接的完成
        // connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
        // fork为每个客户派生一个处理它们的子进程,子关闭监听套接字,父关闭已连接套接字
        if ((childpid = fork()) == -1)
            err_sys("fork error");
        if (0 == childpid) /* child process */
        {
            // Close(listenfd);    /* close listening socket */
            if (close(listenfd) == -1)
            {
                err_sys("close error");
            }
            str_echo(connfd);   /* process the request */
            std::cout << "exiting tcpserv01 child process" << std::endl;
            // 服务器子进程调用exit来终止。服务器子进程中打开的所有描述符随之关闭,
            // 这会导致TCP连接终止序列
            // 的最后两个分节:一个从服务器到客户的FIN,和,一个从客户到服务器的ACK,至此,
            // 连接完全终止,客户套结字进入TIME_WAIT状态。

            // 另一方面
            // when this child is existed, this process will send sigchild signal to parent process
            // and in the parent process, we did not handle this signal, so the child process,
            // this process will be a zombie process, we can see that by command ps ux
            // exit(0);
            return 0;
        }
        // Close(connfd); /* parent closes connected socket */
        if (close(connfd) == -1)
        {
            err_sys("close error");
        }
    }
}

 

#include "../lib/unpsunyj.h"

void sig_chld(int signo)
{
	pid_t	pid;
	int		stat;

	while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0)
		printf("child %d terminated_syj\n", pid);
	return;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

dROSI_008_001ROSI_008_002ROSI_008_003ROSI_008_004ROSI_008_005ROSI_008_006ROSI_008_007ROSI_008_008ROSI_008_009ROSI_008_010ROSI_008_011ROSI_008_012ROSI_008_013ROSI_008_014ROSI_008_015ROSI_008_016ROSI_008_017ROSI_008_018ROSI_008_019ROSI_008_020ROSI_008_021ROSI_008_022ROSI_008_023ROSI_008_024ROSI_008_025ROSI_008_026ROSI_008_027ROSI_008_028ROSI_008_029ROSI_008_030ROSI_008_031ROSI_008_032ROSI_008_033ROSI_008_034ROSI_008_035

posted @ 2015-03-21 13:16  孙永杰  阅读(575)  评论(0编辑  收藏  举报