Linux网络编程之多进程

多进程模型

多进程模型下,注意如何在进程之间通信以及孤儿进程和僵尸进程的处理,可以外配上进程池作为计算任务/异步任务的处理。

//fork server
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <signal.h>

void run();

int main(int argc, char *argv[])
{
    run();
    return 0;
}

void handle_client_socket(int clientfd){
    //read from client socket
    char readbuf[1024];
    ssize_t readlen;
    while(1){
        readlen = read(clientfd, readbuf, sizeof(readbuf));
        if (readlen==-1){
            perror("read client error");
            close(clientfd);
            return;
        }else if(readlen==0){
            break;
        }else{
            fwrite(readbuf, readlen, 1, stdout);
            //write back to client
            if(write(clientfd, readbuf, readlen)==-1){
                perror("write back to client error");
                close(clientfd);
                return;
            }
        }
    }
    close(clientfd);
}

void reap(int signum)
{
    while(waitpid(-1, NULL, WNOHANG)>0);
    return;
}
void run()
{
    //get hostent
    struct hostent *h = gethostbyname("127.0.0.1");
    if(!h){
        perror("resolve host failed");
        exit(EXIT_FAILURE);
    }

    //create server socket
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if(fd==-1){
        perror("socket create failed");
        exit(EXIT_FAILURE);
    }

    //server bind
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_addr = *(struct in_addr *)h->h_addr_list[0];
    server.sin_port = htons(8000);
    if(bind(fd, (struct sockaddr *)&server, sizeof(server))==-1){
        perror("bind error");
        close(fd);
        exit(EXIT_FAILURE);
    }

    int reuse = 1;
    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))<0){
        perror("error setsockopt");
        exit(EXIT_FAILURE);
    }
    //server listen
    if(listen(fd,20)==-1){
        perror("listen error");
        close(fd);
        exit(EXIT_FAILURE);
    }

    signal(SIGCHLD,reap);

    //server loop
    while(1){
        //struct sockaddr_in client;
        struct sockaddr_storage client;
        int clientfd;
        socklen_t socklen = sizeof(client);
        clientfd = accept(fd, (struct sockaddr *)&client, &socklen);
        if (clientfd==-1){
            perror("error accept");
            close(fd);
            exit(EXIT_FAILURE);
        }
        pid_t pid = fork();
        if(pid==-1){
            perror("fork error");
            close(fd);
            exit(EXIT_FAILURE);
        }
        if (pid==0){
            //close parent listening fd
            close(fd);
            handle_client_socket(clientfd);
            exit(EXIT_SUCCESS);
        }
        if (pid>0){
            //close client fd
            close(clientfd);
        }
    }
}
上一篇:jquery处理textarea中的手动换行


下一篇:用代码玩剧本杀?第3届83行代码大赛剧情官方解析