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);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值