您的位置:首页 > 其它

并发服务器---多进程

2017-07-27 14:34 190 查看
下面用多进程方式实现一个TCP并发服务器,每当一个新的客户端连接时fork一个子进程去和它通信。(各种主流的web服务器都不是纯粹的多进程方式运行,比如apache在每个进程中都用多路复用方式,直到连接数多到超过select可监听的最大描述符数时也会利用新的进程去处理。)

服务器端(server.c)

[cpp] view
plain copy

#include<stdio.h>  

#include<stdlib.h>  

#include<string.h>  

#include<sys/types.h>  

#include<sys/socket.h>  

#include<netinet/in.h>  

#include<arpa/inet.h>  

  

  

#define MAX_LISTEN 5  

#define PORT 1987  

#define IP "127.0.0.1"  

  

void serve_proc(int conn_fd)  

{  

    int recv_num;  

    int send_num;  

    char recv_buf[100];  

    char send_buf[100];   

  

    int pid = getpid();  

  

    printf("client %d started\n", pid);  

  

    while (1) {  

        //receive  

        recv_num = recv(conn_fd, recv_buf, sizeof(recv_buf), 0);  

        if (recv_num < 0) {  

            close(conn_fd);  

            exit(1);  

        }  

        recv_buf[recv_num] = '\0';  

        printf("child proc %d got : %s\n", pid, recv_buf);  

  

        if (strcmp(recv_buf,"quit") == 0) {  

            printf("child proc %d quit\n", pid);  

            break;  

        }  

  

        //send  

        sprintf(send_buf, "server proc got %d bytes\n", recv_num);  

        send_num = send(conn_fd, send_buf, strlen(send_buf), 0);  

        if (send_num < 0) {  

            close(conn_fd);  

            exit(1);  

        }  

        printf("child proc %d sent : %s\n", pid, send_buf);  

    }  

  

    close(conn_fd);  

}  

  

int main()  

{  

    pid_t pid;  

  

    int conn_fd;  

    int sock_fd = socket(AF_INET,SOCK_STREAM,0);  

    if (sock_fd < 0) {  

        perror("create socket failed");  

        exit(1);  

    }  

  

    struct sockaddr_in addr_client;  

    int client_size = sizeof(struct sockaddr_in);  

  

    struct sockaddr_in addr_serv;  

    memset(&addr_serv, 0, sizeof(addr_serv));  

    addr_serv.sin_family = AF_INET;  

    addr_serv.sin_port = htons(PORT);  

    addr_serv.sin_addr.s_addr = inet_addr(IP);  

  

    if (bind(sock_fd,(struct sockaddr *)&addr_serv,sizeof(struct sockaddr_in)) < 0) {  

        perror("bind error");  

        exit(1);  

    }  

  

    if (listen(sock_fd,MAX_LISTEN) < 0) {  

        perror("listen failed");  

        exit(1);  

    }  

  

    while (1) {  

        conn_fd = accept(sock_fd, (struct sockaddr *)&addr_client, &client_size);  

        if (conn_fd < 0) {  

            perror("accept failed");  

            exit(1);  

        }  

  

        pid = fork();  

          

        if (pid == 0) { // child proc   

            close(sock_fd);  

            serve_proc(conn_fd);  

        } else { // main proc  

            close(conn_fd);  

        }  

    }  

          

    close(sock_fd);  

    return 0;  

}  

客户端(client.c)

[cpp] view
plain copy

#include<stdio.h>  

#include<stdlib.h>  

#include<string.h>  

#include<sys/types.h>  

#include<sys/socket.h>  

#include<netinet/in.h>  

#include<arpa/inet.h>  

  

#define REMOTE_IP "127.0.0.1"  

#define REMOTE_PORT 1987  

  

int main()  

{  

        int sock_fd = socket(AF_INET, SOCK_STREAM, 0);  

        if (sock_fd < 0) {  

                perror("create socket failed");  

                exit(1);  

        }  

  

        struct sockaddr_in addr_serv;  

        memset(&addr_serv, 0 ,sizeof(addr_serv));  

        addr_serv.sin_family = AF_INET;  

        addr_serv.sin_port = htons(REMOTE_PORT);  

        addr_serv.sin_addr.s_addr = inet_addr(REMOTE_IP);  

  

        if (connect(sock_fd, (struct sockaddr *)&addr_serv, sizeof(struct sockaddr)) < 0) {  

                perror("connect failed");  

                exit(1);  

        }  

  

  

        int send_num, recv_num;  

        char send_buf[100],recv_buf[100];  

  

        while (1) {  

                printf("Input MSG: ");  

                scanf("%s",send_buf);  

                send_num = send(sock_fd, send_buf, strlen(send_buf), 0);  

                if (send_num < 0) {  

                        perror("send error");  

                        exit(1);  

                }  

  

                recv_num = recv(sock_fd, recv_buf, sizeof(recv_buf), 0);  

                if (recv_num < 0) {  

                        perror("recv error");  

                        exit(1);  

                }  

                recv_buf[recv_num] = '\0';  

                printf("Got : %s\n", recv_buf);  

        }  

  

        close(sock_fd);  

        return 0;  

}  

代码都很简单啦,就是基本的收发数据。不过需要注意的一点是fork子进程以后需要对子进程关闭监听套接口,对父进程关闭连接套接口。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: