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

day-07 I/O复用(select)

一.I/O复用

(一)基于I/O复用的服务器端

1.多进程服务器

        每次服务都需要创建一个进程,需要大量的运算和内存空间

2.复用

        只需创建一个进程。

3.复用技术在服务器端的应用

 (二)select函数实现服务器端

  • (Linux和Windows平台下均有select函数,所以具有良好移植性)

1.select函数调用过程:

2.select函数示例:(5秒内控制才没有输入,就输出 Timeout ;否则打印输入。)

#include<iostream>
#include<unistd.h>
#include<sys/time.h>
#include<sys/select.h>
using namespace std;
#define BUF_SIZE 30int main(int argc,char *argv[]){fd_set reads,temps;int result,str_len;//fd_set类型是一个文件描述符集合,char buf[BUF_SIZE];//在这里声明了reads和temps两个集合用于I/O复用。struct timeval timeout;FD_ZERO(&reads);//用于清空文件描述符集合。FD_SET(0,&reads);//将标准输入文件描述符添加到集合中while(1){temps=reads;//在每次循环开始时,将temps设置为上一次存有文件描述符的集合reads的副本。timeout.tv_sec=5;//设置超时时间为5秒timeout.tv_usec=0;result=select(1,&temps,0,0,&timeout);调用select函数来等待可读事件就绪或超时发生。if(result==-1){//第一个参数表示要监视的最大文件描述符值加1,cout<<"select() error"<<endl;//第二个参数是指向待检查的文件描述符集合的指针,break;                       //后面的三个参数是输出参数。}else if(result==0)cout<<"Time out"<<endl;else{if(FD_ISSET(0,&temps))//检查输入文件描述符是否就绪{str_len=read(0,buf,BUF_SIZE);buf[str_len]=0;cout<<"message from console: "<<buf<<endl;}}//如果select函数返回-1,表示出现了错误,输出错误信息并跳出循环。//如果select函数返回0,表示超时,输出"Time out"。//如果select函数返回大于0的值,表示文件描述符就绪。//这里通过FD_ISSET宏检查标准输入文件描述符是否在集合中就绪。//如果标准输入文件描述符就绪,调用read函数读取输入内容,并输出到控制台。}return 0;
}

3.实现I/O复用服务器端

#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<sys/time.h>
#include<sys/select.h>
using namespace std;#define BUF_SIZE 100//宏定义了一个缓冲区大小为100的常量。
void error_handling(const  char *buf);int main(int argc,char *argv[]){int serv_sock,clnt_sock;struct sockaddr_in serv_adr,clnt_adr;struct timeval timeout;fd_set reads,cpy_reads;socklen_t adr_sz;int fd_max,str_len,fd_num,i;char buf[BUF_SIZE];if(argc!=2){cout<<"Usage:"<<argv[0]<<endl;exit(1);}serv_sock=socket(PF_INET,SOCK_STREAM,0);//创建套接字memset(&serv_adr,0,sizeof(serv_adr));//将结构体清零serv_adr.sin_family=AF_INET;serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);//设置服务器地址信息、IP地址和端口号serv_adr.sin_port=htons(atoi(argv[1]));if(bind(serv_sock,(struct sockaddr*)&serv_adr,sizeof(serv_adr))==-1)error_handling("bind() error");      //将套接字和指定地址绑定if(listen(serv_sock,5)==-1)//开始监听连接请求error_handling("listen() error");FD_ZERO(&reads);//清空文件描述符集合FD_SET(serv_sock,&reads);//将服务器套接字添加到reads集合中fd_max=serv_sock;//fd_max初始化为服务器套接字的值while(1){//进入主循环cpy_reads=reads;//将reads集合复制过来timeout.tv_sec=5;//超时时间timeout.tv_usec=5000;if((fd_num=select(fd_max+1,&cpy_reads,0,0,&timeout))==-1)break;        //监控文件描述符的状态变化if(fd_num==0)continue;for(i=0;i<fd_max+1;i++){if(FD_ISSET(i,&cpy_reads)){//检查文件描述符是否就绪if(i==serv_sock){//如果是服务器套接字,表示有新的客户端连接请求adr_sz=sizeof(clnt_adr);clnt_sock=accept(serv_sock,(struct sockaddr*)&clnt_adr,&adr_sz);FD_SET(clnt_sock,&reads);if(fd_max<clnt_sock)fd_max=clnt_sock;cout<<"connect client: "<<clnt_sock<<endl;}else{//如果不是服务器套接字,表示已连接的客户端有数据发送过来str_len=read(i,buf,BUF_SIZE);if(str_len==0){FD_CLR(i,&reads);close(i);cout<<"closed client:"<<i<<endl;}elsewrite(i,buf,str_len);}}}}close(serv_sock);return 0;
}void error_handling(const char *buf){cout<<buf<<endl;exit(1);
}

(三)总结 

1.请解释复用技术的通用含义,并说明何为I/O复用。

复用技术指为了提高物理设备的效率,用最少的物理要素传递最多数据时使用的技术。同样,I/O复用是指将需要I/O的套接字捆绑在一起,利用最少限度的资源来收发数据的技术

2.多进程并发服务器的缺点有哪些?如何在I/O复用服务器端中弥补?

多进程并发服务器的服务方式是,每当客户端提出连接要求时,就会追加生成进程。但构建进程是一项非常有负担的工作,因此,向众多客户端提供服务存在一定的局限性。而复用服务器则是将套接字的文件描述符捆绑在一起管理的方式,因此可以一个进程管理所有的I/O操作

3.select函数的观察对象中应包含服务器端套接字(监听套接字),那么应将其包含到哪一类监听对象集合?请说明原因

服务器套接字的作用是监听有无连接请求,即判断接收的连接请求是否存在?应该将其包含到“读”类监听对象的集合中。

4.select函数使用的fd_set结构体在Windows和Linux中具有不同的声明。请说明却别,同时解释存在区别的必然性

Linux的文件描述符从0开始递增,因此可以找出当前文件描述符数量和最后生成的文件描述符之间的关系。但Windows的套接字句柄并非从0开始,并且句柄的整数值之间并无规律可循,因此需要直接保存句柄的数组和记录句柄数的变量。

相关文章:

day-07 I/O复用(select)

一.I/O复用 &#xff08;一&#xff09;基于I/O复用的服务器端 1.多进程服务器 每次服务都需要创建一个进程&#xff0c;需要大量的运算和内存空间 2.复用 只需创建一个进程。 3.复用技术在服务器端的应用 &#xff08;二&#xff09;select函数实现服务器端 &#xff08;…...

Glide的使用及源码分析

前言 依赖 implementation com.github.bumptech.glide:glide:4.16.0 github: GitHub - bumptech/glide: An image loading and caching library for Android focused on smooth scrolling 基本使用 //加载url Glide.with(this) .load(url) .placeholder(R.drawable.placehol…...

外贸爬虫系统

全球智能搜索 全球智能搜索 支持全球所有国家搜索引擎&#xff0c;及社交平台&#xff0c;精准定位优质的外贸客户&#xff0c;免翻墙 全球任意国家地区实时采集 搜索引擎全网邮箱电话采集 社交平台一键查看采集&#xff08;Facebook,Twitter,Linkedin等&#xff09; 职位…...

CentOS 8 安装 Code Igniter 4

在安装好LNMP运行环境基础上&#xff0c;将codeigniter4文件夹移动到/var/nginx/html根目录下&#xff0c;浏览器地址栏输入IP/codeigniter/pulbic 一直提示&#xff1a; Cache unable to write to "/var/nginx/html/codeigniter/writable/cache/". 找了好久&…...

.net framework 提示安装了 但是删除面板看不到

如果你在计算机上安装了.NET Framework&#xff0c;但在“控制面板”中找不到.NET Framework的相关条目&#xff0c;可能是因为.NET Framework的某些组件或特定版本未在“程序和功能”&#xff08;或旧版本的Windows中称为“程序和功能”&#xff09;列表中列出。这可能是正常情…...

flask-smorest 库

flask-smorest 简介 flask-smorest: 基于Flask/Marshmallow的REST API框架 flask-smorest 是一个用于创建于数据库无关的REST API的架库。 它使用Flask作为Web服务器&#xff0c;并使用marsmallow对数据进行序列化和反序列化。(类似于drf) 快速入门 flask-smorest对代码应…...

android WindowManager的简单使用

<?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"><uses-permission android:name"android.permis…...

Spark_Spark比mapreduce快的原因

Spark 为什么比 mapreduce 快? 最重要的3点&#xff0c; 数据缓存 : 中间结果可以缓存在内存中复用 资源管理 &#xff1a;executor task 管理&#xff0c;不同stage的task可以运行在同一个executor上 任务调度 : dag 对比多阶段mr 1.任务模型的优化&#xff08;DAG图对比…...

el-upload调用内部方法删除文件

从Element UI 的官方文档中&#xff0c; Upload 上传组组件提供了on-remove和before-remove的文件删除的钩子属性&#xff08;回调方法名&#xff09;&#xff0c;但如何调用组件删除方法&#xff08;让该方法删除本地上传文件列表以及触发这两个钩子&#xff09;并无相关说明。…...

无涯教程-JavaScript - CUBEKPIMEMBER函数

描述 该函数返回关键绩效指标(KPI)属性,并在单元格中显示KPI名称。 语法 CUBEKPIMEMBER (connection, kpi_name, kpi_property, [caption])争论 Argument描述Required/OptionalconnectionName of the connection to the cube - A text stringRequiredkpi_nameName of the K…...

代码随想录Day_52打卡

①、最长递增子序列 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序…...

692. 前K个高频单词

题目来源&#xff1a;力扣 题目描述&#xff1a; 给定一个单词列表 words 和一个整数 k &#xff0c;返回前 k 个出现次数最多的单词。 返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率&#xff0c; 按字典顺序 排序。 示例 1&#xff1a; 输入:…...

介绍 Docker 的基本概念和优势,以及在应用程序开发中的实际应用

Docker 是一个开源的容器化平台&#xff0c;可以让开发者将应用程序和其所依赖的组件&#xff08;如库、运行环境&#xff09;打包成一个可移植、自包含的容器。这个容器可以在任何支持 Docker 的环境中运行&#xff0c;包括开发、测试、生产等环境。Docker 的基本概念包括以下…...

C++:构建一个二叉树的代码

​#include <iostream>// 定义二叉树节点 struct BinaryTreeNode {int data;BinaryTreeNode* left;BinaryTreeNode* right;BinaryTreeNode(int val) : data(val), left(nullptr), right(nullptr) {} };// 构建二叉树 BinaryTreeNode* buildBinaryTree() {int val;std::ci…...

iOS 设置下载部分文件,如何获取完整文件的大小

在视频的需求中&#xff0c;遇到这样一个需求&#xff0c;播放一视频的时候&#xff0c;要预下载 后面10条视频&#xff0c;但是只下载后面十条视频的前面1M 实现方法 1 创建请求时设置cacheLength resource [[IdiotResource alloc] init];resource.requestURL task.request…...

如何助力金融贷款企业实现精准营销获客

无论是哪个行业&#xff0c;吸引客户都是核心。 许多公司的线下渠道面临着许多障碍&#xff0c;以至于他们不得不采用在线客户获取方法。受影响最大的行业之一是贷款行业。如何获得准确的贷款客户资源&#xff1f;如何赢得客户已经成为企业的一大痛点。 过去&#xff0c;信贷…...

html中的换行(\n)或回车(\r)符号不起作用的解决办法、br、white、space、pre、line

文章目录 前言html不解释空白字符CSS样式的影响特定的文本区域white-space 前言 如果您的HTML中的换行和回车符号&#xff08;\n和\r&#xff09;似乎不起作用&#xff0c;可能有几种可能的原因&#xff1a; html不解释空白字符 在HTML中&#xff0c;连续的空白字符&#xff0…...

SpringBoot+MyBatisPlus+MySql+vue2+elementUi的案例、java访问数据库服务、java提供接口服务

文章目录 前言后端关键代码前端关键代码完整代码 前言 1、项目不使用前后端分离。 2、在创建SpringBoot的时候要注意各个插件间的版本问题。 3、后端技术SpringBootMyBatisPlusMySql。 4、前端技术vue2elementUi。 后端关键代码 简单介绍 1、数据库名称ssm_db 2、表名称tbl_bo…...

设计模式入门(二)观察者模式

设计模式入门 本系列所有内容参考自《HeadFirst设计模式》。因为书中的代码是采用java语言写的&#xff0c;博主这里用C语言改写。 这里采用讲故事的方式进行讲解。若有错误之处&#xff0c;非常欢迎大家指导。 设计模式&#xff1a;模式不是代码&#xff0c;而针对设计问题的…...

列化复杂的xml对应的类

你能帮我写一个序列化复杂的xml对应的类吗? c#代码 好的,可以试着为一个复杂的XML生成对应的C#类。这里我就简单的XML为例: <Book><Name>Design Patterns</Name><Author>Erich Gamma</Author><Pages>395</Pages><Chapters>…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

redis和redission的区别

Redis 和 Redisson 是两个密切相关但又本质不同的技术&#xff0c;它们扮演着完全不同的角色&#xff1a; Redis: 内存数据库/数据结构存储 本质&#xff1a; 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能&#xff1a; 提供丰…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...