当前位置: 首页 > article >正文

Linux各种并发服务器优缺点

本文旨在介绍针对“无并发C/S模型”改进的方法总结以及各种改进方法的优缺点,具体函数的实现并不介绍。

 

1. 无并发C/S模型

创建服务器流程分析:

  1. socket()创建服务器的监听套接字
  2. bind()将服务器给服务器的监听套接字绑定IP地址和Port端口号
  3. listen()设置服务器端能够连接客户端的最大连接数。默认128
  4. accept()阻塞等待客户端连接,连接成功之后,系统默认创建新的用于与客户端进行数据交换的套接字,accept()返回该数据通信套接字的文件描述符
  5. 与客户端进行数据交换
  6. close()关闭服务器端的俩个套接字
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <errno.h>
#include <ctype.h>
#include <arpa/inet.h>
#define SERV_PORT 9527

void sys_err(const char *str){
    perror(str);
    exit(1);
}

int main(int argc, char *argv[]){
    int lfd = 0 ,cfd = 0;
    int ret,i;
    int buf[BUFSIZ]; //BUFSIZ==4096

    struct sockaddr_in serv_addr;//初始化地址结构体,并给其分配IP和端口号
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(SERV_PORT);
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);//IP地址自动获取

    struct sockaddr_in clit_addr; //accept()的传出参数
    socklen_t clit_addr_len; //accept()的传入传出参数

    lfd = socket(AF_INET,SOCK_STREAM,0);//1.服务器端创建套接字
    if (lfd == -1)
        sys_err("socket error");

    bind(lfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); //2.bind给服务器套接字分配地址

    listen(lfd,128); //3. 设置服务器端最大连接客户端请求上限

    clit_addr_len = sizeof(clit_addr);
    //accept()调用成功的话, clit_addr会保存客户端的地址结构, clit_addr_len保存长度
    cfd = accept(lfd,(struct sockaddr *)&clit_addr, &clit_addr_len);
    if (cfd == -1)
        sys_err("accept error");

    //服务器与客户端建立连接成功----数据通信
    while(1){
        ret = read(cfd,buf,sizeof(buf));
        write(STDOUT_FILENO,buf,ret);

        for (i = 0; i < ret; i++)
            buf[i] = toupper(buf[i]);
        write(cfd,buf,ret);
    }
    close(lfd);
    close(cfd);

    return 0;
}

创建客户端流程分析:

  1. socket()创建套接字
  2. 【bind()给套接字分配IP地址】此步骤可有可无,不调用bind的话系统自动分配
  3. connect()与请求连接服务器
  4. 与服务器进行数据通信
  5. close()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define SERV_PORT 9527
void sys_err(const char *str){
    perror(str);
    exit(1);
}

int main(int argc, char *argv[]){
    int cfd;
    struct sockaddr_in serv_addr; // 服务器的地址结构
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port =htons(SERV_PORT);//存储网络字节序格式的端口号   
    inet_pton(AF_INET,"127.0.0.1",&serv_addr.sin_addr.s_addr);//存储网络字节序的IP地址

    cfd = socket(AF_INET,SOCK_STREAM,0);//1.创建socket套接字
    if (cfd == -1)
        sys_err("socket error");


    int ret = connect(cfd,(struct sockaddr *)&serv_addr, sizeof(serv_addr));//2.与服务器套接字建立连接
    if (ret != 0)
        sys_err("connect err");


    int counter = 10;
    char buf[BUFSIZ];
    while(--counter){//通信
        write(cfd,"hello",5);//写“hello”到缓冲区
        ret = read(cfd,buf,sizeof(buf));//读缓冲区内容到buf中,注意,read是阻塞读取的
        write(STDOUT_FILENO,buf,ret);

    }
    close(cfd);
}

数据通信:

  1. 运行./server
  2. 运行./client, 成功完成数据通信
  3. 再次运行client,此时无法通信

无并发C/S模型模型缺点:

运行server后,accpet只调用了一次,因此当一个client发出连接请求,accpet便不再监听,而是与客户端建立连接,开始通信,无法做到一个server程序同时与多个client通信

2. 多进程C/S模型

3. 多线程C/S模型

4. select模型

5. select多线程模型

6. poll模型

poll的参数:

fds:监听的文件描述符【数组】,该数组的每个成员是struct pollfd

nfds: 监听数组的实际有效监听个数

7. epoll模型


http://www.kler.cn/a/407213.html

相关文章:

  • 医学AI公开课·第一期|Machine LearningTransformers in Med AI
  • 客户流失分析综述
  • 可视化建模与UML《协作图实验报告》
  • Vue3-后台管理系统
  • AWTK fscript 中的 大端小端扩展函数
  • 进程控制(详解)
  • Vue3移动端-点餐项目
  • AOC显示器915Sw按键失灵维修记
  • Java爬虫:获取商品详情的实践之旅
  • 在Ubuntu上使用Python和OpenCV库来处理和显示图片
  • 【学习】使用pam_cracklib校验密码复杂度
  • Java程序设计——(一)Java开发入门(1)Java程序的基本格式
  • Python和Julia(多语言)急性呼吸窘迫综合征
  • 32、js弹框操作
  • Gate学习(5) 指令学习2
  • 精简脂肪:为物联网引入QUIC轻应用
  • 微信小程序条件渲染与列表渲染的全面教程
  • Linux内核(二)——内核编译与安装
  • 【LGR-208-Div.3】洛谷基础赛 #18 P11308 茫茫的不归路
  • 2024 APMCM亚太数学建模C题 - 宠物行业及相关产业的发展分析和策略(详细解题思路)
  • 【jvm】new对象的过程
  • 活着就好20241124
  • Ansys Zemax Optical Studio 中的近视眼及矫正
  • 项目实战:基于Vue3实现一个小相册
  • mips架构下编译nginx-rtmp
  • 分类算法——基于heart数据集实现