千家信息网

多线程网络服务

发表于:2025-01-20 作者:千家信息网编辑
千家信息网最后更新 2025年01月20日,1、多线程网络服务:多线程网络模式类似于多进程网络模式;不同的是:新客户端到来时,启动的是一个线程(每来一个客户,将创建一个线程)。模型分析2、代码实现同样用处理整数运算来模拟多线程的并发处理(1)、
千家信息网最后更新 2025年01月20日多线程网络服务

1、多线程网络服务

:多线程网络模式类似于多进程网络模式;不同的是:新客户端到来时,启动的是一个线程(每来一个客户,将创建一个线程)。

模型分析


2、代码实现

同样用处理整数运算来模拟多线程的并发处理

(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* Thread_Handler(void *arg);void* Thread_Handler(void *arg){    int sockConn = *(int *)arg;    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);    pthread_exit(0);}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));        }        pthread_t tid;        pthread_create(&tid, NULL, Thread_Handler, &sockConn);            }    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

客户2

3、分析总结

多线程网络服务也存在线程的动态申请与释放,还是有一定的开销,若存在大量用户在线,很可能带来线程间切换开销。



0