1.单循环服务器

2.并发服务器

1. 设置socket属性

2. 进程

​3. 线程

3.多路IO复用模型 - 提高并发程度

1. 区别

2. IO处理模型

1. 阻塞IO模型

2. 非阻塞IO模型

3. 信号驱动IO

4. IO多路复用

3. 特点

4. 函数接口

1. select

2. poll

3. epoll

半包


1.单循环服务器

2.并发服务器

1. 设置socket属性

原型:int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen)
功能:
在bind前 设置socket的属性
参数:
        sockfd        要设置的socket
        level           设置socket层次//socket本身 tcp ip
        optname    选项名字
        optval        选项值
        optlen        长度
设置一个选项(开启一个功能))---让地址重用,即可停止后立即使用
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int));

2. 进程:

ps aux | grep ser        查找包含ser的进程


signal(SIGCHILD, do_child)       

父进程接收子进程结束信号exit(0)后回收子进程资源,防止僵尸态


void do_child(int signo)
{        wait(NULL);}


3. 线程:

退出个体线程使用pthread_exit(NULL)
pthread_join()会阻塞程序,无法接收多个客户端信息,所以选择pthread_detach()回收资源

3.多路IO复用模型 - 提高并发程度

1. 区别

多进程和多线程:一个客户端对应一个进程或线程
IO多路复用       :多个客户端对应一个进程或线程

2. IO处理模型

1. 阻塞IO模型:

特点:简单,低效

i - 读:scanf, getchar,read,recv
            操作:从终端stdin读取数据 => 阻塞等待读取数据 => 返回用户空间

o- 写:pipe(一直向管道写入数据,管道内存满时阻塞)

2. 非阻塞IO模型

特点:轮询,CPU负担重

操作:从终端stdin读取数据 => 不等待读取数据 => 直接返回用户空间
           O_NONBLOCK 打开文件时可以设置为非阻塞模式

3. 信号驱动IO

设置非阻塞:fcntl,并与信号结合

特点:处理多路IO时资源数量有限

  • 原型:int fcntl(int fd, int cmd, ...)
  • 功能:

维护文件描述符

  • 参数

        fd                  要操作的fd
        cmd              要做的操作

                                F_GETFL                   开启异步信号

                                F_SETFL                   

                                F_SETOWN              设置与信号的关联

                                                                        fcntl(fd, F_SETOWN, gtpid());
        ...                  可变参数                             eg:printf(const char *format,...);                                                                                                      printf("hello");        printf("a = %d\n", a);

  • 返回值

成功时返回值取决于所作的操作

与信号的结合:signo

4. IO多路复用

3. 特点

1. 可以处理多路IO

2. 不需要阻塞

3. 不需要轮询

4. 函数接口

1. select

  • 原型:int select(int nfds,
                            fd_set *readfds,
                            fd_set *writefds,
                            fd_set *exceptfds,
                            struct timeval *timeout);
  • 功能:

        实现IO多路复用

  • 参数

                nfds                      文件描述符中最大文件描述符+1

                                                      遍历时即可遍历到自己  for(i = 0; i < nfds; i++)
                readfds                 读操作的文件描述符的集合
                writefds                写操作的文件描述符的集合
                exceptfds             异常的文件描述符的集合
                timeout                 设置超时时间               struct timeval_t = {3, 0}; //阻塞3秒

                                             NULL表示select是阻塞功能

                                                                0         -  非阻塞

                                                                n > 0  -  每次阻塞的时间

  • 返回值

        成功返回就绪的文件描述符的数量

        失败返回-1

1. 辅助函数

void FD_CLR(int fd, fd set *set);                // 将fd从set集合中清除
int FD_ISSET(int fd, fd_set *set);               // 判断fd是否在set中
void FD_SET(int fd, fd_set *set);             // 将fd添加到set集合中
void FD_ZERO(fd_set *set);t*set);             // 将set集合清空

2. 步骤

1. 建立一张表        监控

        fd_set readfds ;                        建立表

        FD_ZERO(&readfds)                清空表

2. 将要监控的文件描述符加入表中

        FD_SET(0,&readfds);             0表示标准输入

        FD_SET(fd,&readfds); 

3.准备参数

        nfds = fd + 1

        select(nfs, &readfds, NULL, NULL, NULL);

4. 监控文件描述符

3. 缺点

1.最大监听数受限:FD_SETSIZE 默认1024(Linux)
2.每次调用需重置fdSet:内核会修改集合,必须每次重新
3.用户态与内核态拷贝开销大
4.返回后仍需遍历所有fd才能知道哪个就绪
5.效率随fd数量增长下降明显

4. 点对点聊天

server.c:

client.c:

超时设置:

5. 多路IO复用

server.c

client.c:

                                                                                                                           (退出.quit不管用)

                                                                                                解决: 使用strncpy函数除去输入的\n

2. poll

  • 原型:int poll(struct pollfd *fds, nfds_t nfds, int timeout);

        struct pollfd {
               int   fd;         /* file descriptor */
               short events;     /* requested events */
               short revents;    /* returned events */
           };

  • 功能:

        对文件描述符监控

  • 参数:

               events                事件:POLLIN        读

                                                    POLLOUT     写

                                                    POLLERR     错误
               revents                返回就绪的事件

                nfds                    监控的文件描述符的个数

                timeout                时间值,-1阻塞        时间值,单位ms

                                                            0非阻塞

  • 返回值

        成功返回就绪文件的数量,0 超时情况下没有就绪事件

        失败返回 -1

1. 步骤

1. 建立监控表        

        struct pollfd fds[10];        // 监控10个fd

2. 将要监控的文件描述符加入表中

        两路:int nfds = 0;

                   fds[0].fd = 0;                                                fds[1].fd = sockfd;

                   fds[0].events = POLLIN | POLLOUT;          fds[0].events = POLLIN | POLLOUT;

                   nfds++;                                                        nfds++;

                   // 关心读和写,只会返回就绪的事件

3.准备参数

4. 监控文件描述符

2. 改进与缺点
  • 相比select的改进

1.无1024限制:只要系统允许打开足够多fd
2.无需重置集合:^events和」revents丶分离
3.更清晰的事件机制
4.效率更高:仅遍历传入的数组,不遍历整个fd范围

  • 仍存在的问题

1.每次调用仍需将整个fds[]拷贝到内核
2.返回后仍需遍历全部元素查找就绪fd
3.时间复杂度仍是O(n),连接数多时性能下降

3. 点对点聊天

server.c:

client.c:

4. 多路IO复用

server.c:


3. epoll

1. epoll_create
  • 原型:int epoll_create(int size)
  • 功能:

        创建一个epoll对象

  • 参数:

        size        忽略,但是必须大于0

  • 返回值

        成功返回epoll对象的fd

        失败返回-1

2. epoll_ctl
  • 原型:int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
  • 功能:

        控制epoll对象

  • 参数:

        epfd                          epoll对象的fd

        op                    EPOLL_CTL_ADD         添加

                                EPOLL_CTL_MOD        修改

                                EPOLL_CTL_DEL          删除

        fd                             关心的文件描述符

        event               事件                

                                typedef union epoll_data {
                                       void           *ptr;
                                       int               fd;
                                       uint32_t     u32;
                                       uint64_t     u64;
                                } epoll_data_t;

           -------------------------------------------------------------------------------------------------------

                                struct epoll_event {
                                       uint32_t     events;      // EPOLLIN                读

                                                                          // EPOLLOUT             写

                                                                          // EPOLLERR             出错

                                                                          // EPOLLET                边沿触发
                                      epoll_data_t data;        
                                };

  • 返回值

        成功返回0,失败返回-1

中断

1. 水平(电平)触发

        有数据就会一直通知

2. 边沿触发

        每完成从没数据到有数据的过程,通知一次

3. epoll_wait
  • 原型:int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
  • 功能:

        监控对应文件描述符,查看是否就绪

  • 参数:

        epfd                    epoll对象

        events                保存就绪结果的数组的首地址
        maxevents          数组大小

        timeout                设置超时时间,单位ms

  • 返回值:

        成功返回就绪数量,失败返回-1

4. 步骤

1. 创建一个epoll对象 -- 监控的表

        int epfd = epoll_create(2);

2. 添加文件描述符

        int add_fd(int fd, int epfd)

        {

                struct epoll_event ev;

                ev.events = EPOLLIN;

                ev.data.fd = fd;

                if( epoll_ctl(epfd,EPOLL_CTL_ADD, fd, &ev) < 0)

                {        perror("fail to add");        return -1;}

                return 0;

        }

        add_fd(0, epfd);

        add_fd(fd, epfd);

删除文件描述符

        int del_fd(int fd, int epfd) 
        {
            if ( epoll_ctl(epfd,EPOLL_CTL_DEL, fd, NULL))
            {        perror("fail to delte");        return -1; }    
            return 0;
        }

 3. 监控文件描述符

5. 点对点聊天

server.c

client.c


半包

想要接受4000的数据,但网络层一次只能打包1500字节的数据

解决:多接受几次,注意越界判断

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/94596.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/94596.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/94596.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mybatis中缓存机制的理解以及优缺点

文章目录一、MyBatis 缓存机制详解1. 一级缓存&#xff08;Local Cache&#xff09;2. 二级缓存&#xff08;Global Cache&#xff09;3. 缓存执行顺序二、MyBatis 缓存的优点三、MyBatis 缓存的缺点四、适用场景与最佳实践总结MyBatis 提供了完善的缓存机制&#xff0c;用于减…

Rust 登堂 之 类型转换(三)

Rust 是类型安全的语言&#xff0c;因此在Rust 中做类型转换不是一件简单的事&#xff0c;这一章节&#xff0c;我们将对Rust 中的类型转换进行详尽讲解。 高能预警&#xff0c;本章节有些难&#xff0c;可以考虑学了进阶后回头再看 as 转换 先来看一段代码 fn main() {let a…

【MySQL 为什么默认会给 id 建索引? MySQL 主键索引 = 聚簇索引?】

MySQL 索引 MySQL 为什么默认会给 id 建索引&#xff1f; & MySQL 主键索引 聚簇索引&#xff1f; 结论&#xff1a;在 MySQL (InnoDB) 中&#xff0c;主键索引是自动创建的聚簇索引&#xff0c;不需要删除&#xff0c;其他索引是补充优化。 1. MySQL 的id 索引是怎么来的…

[光学原理与应用-321]:皮秒深紫外激光器产品不同阶段使用的工具软件、对应的输出文件

在皮秒深紫外激光器的开发过程中&#xff0c;不同阶段使用的工具软件及其对应的输出文件如下&#xff1a;一、设计阶段工具软件&#xff1a;Zemax OpticStudio&#xff1a;用于光学系统的初步设计和仿真&#xff0c;包括光线追迹、像差分析、优化设计等。MATLAB&#xff1a;用于…

openEuler常用操作指令

openEuler常用操作指令 一、前言 1.简介 openEuler是由开放原子开源基金会孵化的全场景开源操作系统项目&#xff0c;面向数字基础设施四大核心场景&#xff08;服务器、云计算、边缘计算、嵌入式&#xff09;&#xff0c;全面支持ARM、x86、RISC-V、loongArch、PowerPC、SW…

Python爬虫实战:构建网易云音乐个性化音乐播放列表同步系统

1. 引言 1.1 研究背景 在数字音乐生态中,各大音乐平台凭借独家版权、个性化推荐等优势占据不同市场份额。根据国际唱片业协会(IFPI)2024 年报告,全球流媒体音乐用户已突破 50 亿,其中超过 60% 的用户同时使用 2 个及以上音乐平台。用户在不同平台积累的播放列表包含大量…

vscode 配置 + androidStudio配置

插件代码片段 饿了么 icon{"Print to console": {"prefix": "ii-ep-","body": ["i-ep-"],"description": "elementPlus Icon"} }Ts 初始化模版{"Print to console": {"prefix": &q…

DQN(深度Q网络):深度强化学习的里程碑式突破

本文由「大千AI助手」原创发布&#xff0c;专注用真话讲AI&#xff0c;回归技术本质。拒绝神话或妖魔化。搜索「大千AI助手」关注我&#xff0c;一起撕掉过度包装&#xff0c;学习真实的AI技术&#xff01; ✨ 1. DQN概述&#xff1a;当深度学习遇见强化学习 DQN&#xff08;D…

个人博客运行3个月记录

个人博客 自推一波&#xff0c;目前我的Hexo个人博客已经优化的足够好了&#xff0c; 已经足够稳定的和简单进行发布和管理&#xff0c;但还是有不少问题&#xff0c;总之先记下来再说 先总结下 关于评论系统方面&#xff0c;我从Waline (快速上手 | Waline) 更换成了&#x…

C89标准关键字以及运算符分类汇总

开发单片机项目学好C语言尤其重要&#xff0c;我感觉学习C语言需要先学好关键字和运算符&#xff0c;我对C语言的关键字和运算符做一下汇总。一、关键字&#xff1a;&#xff08;C89标准一共有32个关键字&#xff09;(1) 数据类型关键字&#xff08;一共12个&#xff0c;分为基…

吱吱企业通讯软件打破跨部门沟通壁垒,为企业搭建安全的通讯环境

在数字化转型浪潮中&#xff0c;企业通讯软件不再仅仅作为企业跨部门沟通桥梁&#xff0c;更是承载着保护通讯数据安全的使命。吱吱企业通讯凭借其“私有化部署全链路加密”双重机制&#xff0c;为企业构建了一套“沟通便捷、通讯安全”的数字化通讯解决方案。 一、打破沟通壁垒…

Day16_【机器学习建模流程】

一、机器学习建模流程&#xff1a;获取数据&#xff08;搜集与完成机器学习任务相关的数据集&#xff09;数据基本处理&#xff08;数据 缺失值处理&#xff0c;异常值处理&#xff09;特征工程&#xff08;特征提取、特征预处理 、特征降维、特征选择 、特征组合&#xff09;机…

【不说废话】pytorch中.to(device)函数详解

1. 这个函数是什么&#xff1f; .to(device) 是 PyTorch 中一个用于张量和模型在设备&#xff08;CPU 或 GPU&#xff09;之间移动的核心函数。这里的 “设备” &#xff08;device&#xff09; 通常指的是计算发生的硬件位置&#xff0c;最常见的是&#xff1a; CPU&#xff1…

基于matplotlib库的python可视化:以北京市各区降雨量为例

一、实验目的1. 掌握使用Python的pandas、matplotlib和seaborn库进行数据可视化的方法 2. 学习制作杠铃图、堆积柱状图和折线图等多种图表类型 3. 分析北京市各区在特定时间段内的降雨量的变化规律 4. 培养数据分析和可视化的实践能力二、实验数据数据来源&#xff1a;北京市水…

SCDN如何提示网站性能和安全防护

SCDN&#xff08;Secure Content Delivery Network&#xff0c;安全内容分发网络&#xff09;是融合了传统 CDN&#xff08;内容分发网络&#xff09;性能加速能力与专业安全防护能力的新一代网络服务&#xff0c;核心目标是在 “快速分发内容” 的基础上&#xff0c;同步解决网…

PowerShell远程加载Mimikatz完全指南:从原理到实战

PowerShell远程加载Mimikatz完全指南&#xff1a;从原理到实战无文件攻击技术是现代渗透测试的核心技能&#xff0c;掌握PowerShell远程加载Mimikatz对白帽子黑客至关重要1 引言 在当今的网络安全领域&#xff0c;无文件攻击(fileless attack)已成为高级持久性威胁(APT)的主要手…

基于Spring Boot的民宿服务管理系统-项目分享

基于Spring Boot的民宿服务管理系统-项目分享项目介绍项目摘要系统总体结构图民宿资讯信息实体图项目预览民宿信息管理页面民宿咨询管理页面已支付订单管理页面用户主页面写在最后项目介绍 使用者&#xff1a;管理员、用户 开发技术&#xff1a;MySQLJavaSpringBootVue 项目摘…

SpringBoot基础知识-从XML配置文件到Java Config

项目结构与依赖首先&#xff0c;我们需要添加 Spring 核心依赖&#xff1a;<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.5.RELEASE</version> </dependency>项目…

用无标签语音自我提升音频大模型:SI-SDA 方法详解

用无标签语音自我提升音频大模型:SI-SDA 方法详解 在语音识别和处理领域,近年来大模型(Large Language Models, LLMs)的发展迅速,为语音任务带来了新的突破。然而,语音信号的复杂性使得这些模型在特定领域中表现不佳。如何在没有标注数据的情况下提升音频大模型的表现?…

开源工具新玩法:cpolar提升Penpot协作流畅度

文章目录前言1. 安装Docker2. Docker镜像源添加方法3. 创建并启动Penpot容器3. 本地使用Penpot进行创作4. 公网远程访问本地Penpot4.1 内网穿透工具安装4.2 创建远程连接公网地址5. 固定Penpot公网地址前言 你是否也曾因商业设计软件的高昂费用而放弃团队协作&#xff1f;或者…