千家信息网

多进程网络服务

发表于:2025-01-20 作者:千家信息网编辑
千家信息网最后更新 2025年01月20日,1、高性能网络服务程序Linux的一个应用优势是可用于设计各种高性能网络服务程序,高性能的一个特点就是实现并发访问处理,及同时为多个在线用户提供服务;多进程网络服务、多线程网络服务、线程池网络服务;2
千家信息网最后更新 2025年01月20日多进程网络服务

1、高性能网络服务程序

Linux的一个应用优势是可用于设计各种高性能网络服务程序,高性能的一个特点就是实现并发访问处理,及同时为多个在线用户提供服务;多进程网络服务、多线程网络服务、线程池网络服务;

2、多进程网络服务

:利用Linux系统中的父子进程关系为多用户提供并发服务,是一种比较流行的并发服务技术,其基本理念是:来一个用户,启动一个服务进程。若有新连接到来,则启动子进程与其交互,服务结束后,其子进程自动退出。

模型如下:


3、代码实现:

用一个整数的运算模拟多进程的网络服务。

(1)、utili.h

#include#include#include#include#include#include#include#include#define SERVER_PORT  9090#define SERVER_IP    "127.0.0.1"#define LISTEN_QUEUE  5#define BUFFER_SIZE   255typedef enum{ADD,SUB,MUL,DIV,MOD, QUIT}OPER_TYPE;typedef struct OperStruct{    int op1;    int op2;    OPER_TYPE oper;}OperStruct;

(2)、ser.c

#include"../utili.h"void Process_Handler(int sockConn);void Process_Handler(int sockConn){    OperStruct op;     int result;    while(1){        int res = recv(sockConn, &op, sizeof(op), 0);         if(res == -1){            printf("recv data fail.\n");            continue;        }           if(op.oper == ADD){            result = op.op1 + op.op2;        }else if(op.oper == SUB)        {               result = op.op1 - op.op2;        }else if(op.oper == MUL){            result = op.op1 * op.op2;        }else if(op.oper == DIV){            result = op.op1 / op.op2;        }else if(op.oper == QUIT){            break;        }           res = send(sockConn, &result, sizeof(result), 0);         if(res == -1){            printf("send data fail.\n");            continue;        }    }    close(sockConn);}int main(void){    int sockSer = socket(AF_INET, SOCK_STREAM, 0);    if(sockSer == -1){        perror("socket");        return -1;    }    struct sockaddr_in addrSer, addrCli;    addrSer.sin_family = AF_INET;    addrSer.sin_port = htons(SERVER_PORT);    addrSer.sin_addr.s_addr = inet_addr(SERVER_IP);    socklen_t len = sizeof(struct sockaddr);    int res = bind(sockSer, (struct sockaddr*)&addrSer, len);    if(res == -1){        perror("bind");        close(sockSer);        return -1;          }    listen(sockSer, LISTEN_QUEUE);    int sockConn;    while(1){        printf("Server Wait Client Connect.......\n");        sockConn = accept(sockSer, (struct sockaddr*)&addrCli, &len);        if(sockConn == -1){            printf("Server Accept Client Connect Fail.\n");            continue;        }else{            printf("Server Accept Client Connect Success.\n");            printf("Client IP:>%s\n", inet_ntoa(addrCli.sin_addr));            printf("Client Port:>%d\n",ntohs(addrCli.sin_port));        }        pid_t pid;        pid = fork();        if(pid == 0){            close(sockSer);            Process_Handler(sockConn);            exit(0);        }else if(pid > 0){            close(sockConn);            continue;            }else{            printf("Create Process Fail.\n");            continue;        }    }    close(sockSer);    return 0;}

(3)、cli.c

#include"utili.h"void InputData(OperStruct *pt);void InputData(OperStruct *pt){    printf("please input op1 and op2 : ");    scanf("%d %d", &(pt->op1), &(pt->op2));}//Cliint main(void){    int sockCli = socket(AF_INET, SOCK_STREAM, 0);     if(sockCli == -1){        perror("socket");        return -1;     }       struct sockaddr_in addrSer;    addrSer.sin_family = AF_INET;    addrSer.sin_port = htons(SERVER_PORT);    addrSer.sin_addr.s_addr = inet_addr(SERVER_IP);    socklen_t len = sizeof(struct sockaddr);    int res = connect(sockCli, (struct sockaddr*)&addrSer, len);    if(res == -1){        perror("connect");        close(sockCli);        return -1;     }else{        printf("Client Connect Server Success.\n");    }    char cmd[2];    OperStruct  op;    int result;    while(1){        printf("Please input operator : ");        scanf("%s",cmd);        if(strcmp(cmd, "+") == 0){            op.oper = ADD;            InputData(&op);        }else if(strcmp(cmd,"-") == 0){            op.oper = SUB;            InputData(&op);        }else if(strcmp(cmd,"*") == 0){            op.oper = MUL;            InputData(&op);        }else if(strcmp(cmd,"/") == 0){            op.oper = DIV;            InputData(&op);        }else if(strcmp(cmd, "quit") == 0){            op.oper = QUIT;        }else{                printf("Cmd invalid.\n");        }        res = send(sockCli, &op, sizeof(op), 0);        if(res == -1){            printf("send data fail.\n");            continue;        }        if(op.oper == QUIT)            break;        res = recv(sockCli, &result, sizeof(result), 0);        if(res == -1){            printf("recv data fail.\n");            continue;        }        printf("result = %d\n", result);    }    close(sockCli);    return 0;}

运行结果:

服务器端

客户1

客户1

客户2

4、结果分析

(1)、utili.h在ser.c的上一层目录,utili.h和cli.c是在同一层目录;

(2)、进程服务器:socker是引用计数器模型,close()是减少一个,并没有真正的关闭,每次创建一个进程都会给socker引用计数器加1;

(3)、缺点:a、启动和关闭子进程带来很大的开销;b、系统最多只能产生512个进程,也就是说最多只有512个客户,形成不了处理大型访问的情形;



0