zoukankan      html  css  js  c++  java
  • 简单回射程序之处理僵死进程版服务器程序

    一、server.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <unistd.h>
    #include <signal.h>
    #include <sys/socket.h>
    
    #define SERV_PORT 9999
    #define MAXLINE 4096
    #define LISTENQ 1024
    #define SA struct sockaddr
    
    typedef void Sigfunc(int);
    
    void str_echo(int);
    void sig_chld(int);
    ssize_t writen(int, const void*, size_t);
    Sigfunc *signal(int, Sigfunc*);
    
    int main(int argc, char *argv[]) {
        int listenfd, connfd;
        pid_t childpid;
        socklen_t clilen;
        struct sockaddr_in cliaddr, servaddr;
    
        listenfd = socket(AF_INET, SOCK_STREAM, 0);
    
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        servaddr.sin_port = htons(SERV_PORT);
    
        bind(listenfd, (SA *)&servaddr, sizeof(servaddr));
    
        listen(listenfd, LISTENQ); 
    
        signal(SIGCHLD, sig_chld); /* Install signal processing function */
    
        for ( ; ; ) {
            clilen = sizeof(cliaddr);
            connfd = accept(listenfd, (SA *)&cliaddr, &clilen);
    
            if ( (childpid = fork()) == 0) { /* Generate child processes to handle foreign connections */
                close(listenfd);
                str_echo(connfd);
                exit(0);
            }
            close(connfd);
        }
        close(listenfd);
        exit(0);
    }
    
    void str_echo(int sockfd) {
        ssize_t n;
        char buf[MAXLINE];
    
        again:
        while ( (n = read(sockfd, buf, MAXLINE)) > 0) {
            writen(sockfd, buf, n);
            bzero(buf, sizeof(buf));
        }
        if (n < 0 && errno == EINTR) {
            goto again;
        } else if (n < 0) {
            perror("read");
        }
    }

    二、writen.c

    #include <unistd.h>
    #include <errno.h>
    
    ssize_t writen(int fd, const void *vptr, size_t n) {
        size_t nleft;
        ssize_t nwriten;
        const char *ptr;
    
        ptr = vptr;
        nleft = n;
        while (nleft > 0) {
            if ( (nwriten = write(fd, ptr, nleft)) <= 0) {
                if (nwriten < 0 && errno) {
                    nwriten = 0; /* call write() again */
                } else {
                    return (-1); /* error */
                }
            } 
            nleft -= nwriten;
            ptr += nwriten;
        }
        return (n - nwriten);
    }

    三、signal.c

    #include <signal.h>
    
    typedef void Sigfunc(int);
    
    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, 4.4BSD */
    #endif
        }
        if (sigaction(signo, &act, &oact) < 0) {
        return SIG_ERR;
        }
        return (oact.sa_handler);
    }

    四、sig_chld.c

    #include <stdio.h>
    #include <sys/wait.h>
    
    void sig_chld(int signo) {
        pid_t pid;
        int stat;
        
        pid = wait(&stat);
        printf("child %d terminated
    ", pid);
        return;
    }

    五、Makefile

    target=server
    cc=gcc
    $(target):writen.o server.o signal.o sig_chld.o
            $(cc)  writen.o server.o signal.o sig_chld.o -o $(target)
    writen.o:writen.c
            $(cc) -c writen.c -o writen.o
    server.o:server.c
            $(cc) -c server.c -o server.o
    signal.o:
            $(cc) -c signal.c -o signal.o
    sig_chld.o:
            $(cc) -c sig_chld.c -o sig_chld.o
    clean:
            rm -rf *.o $(target)                            
  • 相关阅读:
    8种元素定位方式
    接口MD5加密如何测试?
    web自动化测试框架 —数据驱动测试
    等待方式
    全面开展测试需求分析
    字符串格式化(%方式 与 format方式)
    Python中八大基本数据类型之 集合
    Python中 __new__ 和 __init__ 的区别
    C/S模式与B/S模式的工作原理
    剑指offer--把二叉树打印成多行
  • 原文地址:https://www.cnblogs.com/soldierback/p/10695252.html
Copyright © 2011-2022 走看看