美文网首页
多进程网络服务

多进程网络服务

作者: 编程小兔崽 | 来源:发表于2018-11-04 21:02 被阅读4次

    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个客户,形成不了处理大型访问的情形;

    喜欢本文的朋友们,欢迎长按下图关注订阅号编程小兔崽,收看更多精彩内容

    每天进步一点点,如果有用给小编点个赞

    想了解更多文章可以观看-Socket网络编程

    想了解更多文章请观看-线程高级操作

    想了解更多文章请观看-Linux多线程编程

    想了解更多文章请观看-线程

    相关文章

      网友评论

          本文标题:多进程网络服务

          本文链接:https://www.haomeiwen.com/subject/zwpdxqtx.html