zoukankan      html  css  js  c++  java
  • UNIX网络编程5.8POSIX信号处理5.9处理SIGCHLD信号

    HCTTC{@%K(]C9J@E{{KVXC4

    信号signal就是告知某个进程发生了某个事件的通知,有时也称为软件中断(software interrupt),信号通常是异步发生的,也就是说,进程预先不知道信号的准确发生时间。

    信号可以:

    由一个进程发给另一个进程(或者自身)。

    由内核发给某进程。

    }UCVXA40X{5KI6VV[N2NINW

    G3R{B%4UX7ANO7{_7Q~103U

    /* include signal */
    #include "unpsunyj.h"
    
    Sigfunc* signal(int signo, Sigfunc *func)
    {
        struct sigaction act, oact;
    
        act.sa_handler = func;
        sigemptyset(&act.sa_mask);
        act.sa_flags = 0;
        if (signo == SIGALRM) {
    #ifdef SA_INTERRUPT
            act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */
    #endif
        } else {
    #ifdef SA_RESTART
            act.sa_flags |= SA_RESTART; /* SVR4, 44BSD */
    #endif
        }
        if (sigaction(signo, &act, &oact) < 0)
            return(SIG_ERR);
        return(oact.sa_handler);
    }
    /* end signal */
    
    Sigfunc* Signal(int signo, Sigfunc *func) /* for our signal() function */
    {
        Sigfunc* sigfunc;
    
        if ( (sigfunc = signal(signo, func)) == SIG_ERR)
            err_sys("signal error");
        return(sigfunc);
    }
    

    )(C8W_3`S[3X7KLA_HSGY5O

    SW@X19~~LJNNQU03A7V%_7Y

    H0GJ~T8Q~4_(DFV(P[{1TZS

    RD0[GHL1_(``IS[Z~1B$ZEY

    }JC___YMHVQIVX{E)R[44SS

    5HUB01P$7S75]PW%]0){{TF

    DC8AE{YF]5Q2TYJX}SYG7}L

    #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;
                }
    #ifdef  EPROTO
                if (errno == EPROTO || errno == ECONNABORTED)
    #else
                    if (errno == ECONNABORTED)
    #endif
                        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;
    
        pid = wait(&stat);
        printf("child %d terminated
    ", pid);
        return;
    }
    
    /* include unph */
    /* Our own header.  Tabs are set for 4 spaces, not 8 */
    
    #ifndef	__unp_h
    #define	__unp_h
    
    #include <stdlib.h>
    #include <errno.h>
    #include <stdio.h>
    #include <cstring>
    #include <unistd.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <signal.h>
    #include <sys/wait.h>
    
    #include "../config.h" /* configuration options for current OS */
                           /* "../config.h" is generated by configure */
    /* Miscellaneous constants */
    #define MAXLINE  4096 /* max text line length */
    #define BUFFSIZE 8192 /* buffer size for reads and writes */
    #define LISTENQ  1024 /* 2nd argument to listen() */
    
    /* Define some port number that can be used for our examples */
    #define SERV_PORT       9877              /* TCP and UDP */
    #define SERV_PORT_STR   "9877"            /* TCP and UDP */
    #define UNIXSTR_PATH    "/tmp/unix.str"   /* Unix domain stream */
    #define UNIXDG_PATH     "/tmp/unix.dg"    /* Unix domain datagram */
    
    typedef void Sigfunc(int);   /* for signal handlers */
    Sigfunc* Signal(int signo, Sigfunc *func); /* for our signal() function */
    void sig_chld(int);
    
    
    void err_dump(const char *, ...);
    void err_msg(const char *, ...);
    void err_quit(const char *, ...);
    void err_ret(const char *, ...);
    void err_sys(const char *, ...);
    
    void str_echo(int sockfd);
    void str_cli(FILE *fp, int sockfd);
    
    char* Fgets(char *ptr, int n, FILE *stream);
    void Fputs(const char *ptr, FILE *stream);
    
    ssize_t Readline(int fd, void *ptr, size_t maxlen);
    
    void Writen(int, void *, size_t);
    
    #endif	/* __unp_h */
    

    dROSI_007_001ROSI_007_002

    ROSI_007_003ROSI_007_004ROSI_007_005ROSI_007_006ROSI_007_007ROSI_007_008ROSI_007_009ROSI_007_010ROSI_007_011ROSI_007_012ROSI_007_013ROSI_007_014ROSI_007_015ROSI_007_016ROSI_007_017ROSI_007_018ROSI_007_019ROSI_007_020

    ROSI_007_021ROSI_007_022ROSI_007_023ROSI_007_024ROSI_007_025ROSI_007_026ROSI_007_027ROSI_007_028ROSI_007_029ROSI_007_030ROSI_007_031ROSI_007_032ROSI_007_033ROSI_007_034ROSI_007_035ROSI_007_036ROSI_007_037ROSI_007_038ROSI_007_039ROSI_007_040ROSI_007_041ROSI_007_042ROSI_007_043ROSI_007_044ROSI_007_045ROSI_007_046ROSI_007_047ROSI_007_048ROSI_007_049ROSI_007_050ROSI_007_051ROSI_007_052ROSI_007_053ROSI_007_054

  • 相关阅读:
    nodeJs爬虫小程序练习
    promise
    node-并发控制
    高性能Js—数据存取
    javascript测试框架mocha
    npm、模块暴露,小知识点区别
    高性能Js-加载和执行
    Request对象获得参数方法:query和body方法
    nvm工具
    在express中提供静态文件笔记
  • 原文地址:https://www.cnblogs.com/sunyongjie1984/p/4347931.html
Copyright © 2011-2022 走看看