26-LINUX--I/O复用-select
一.I/O复用概述
/O复用使得多个程序能够同时监听多个文件描述符,对提高程序的性能有很大帮助。以下情况适用于I/O复用技术:
二.select机制
1.select接口介绍
#include <sys/select.h>int select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct ti
meval *timeout);/*select 成功时返回就绪(可读、可写和异常)文件描述符的总数。如果在超时时间内
没有任何文件描述符就绪,select 将返回 0。select 失败是返回-1.如果在 select 等待
期间,程序接收到信号,则 select 立即返回-1,并设置 errno 为 EINTR。maxfd 参数指定的被监听的文件描述符的总数。它通常被设置为 select 监听的所
有文件描述符中的最大值+1readfds、writefds 和 exceptfds 参数分别指向可读、可写和异常等事件对应的文件
描述符集合。应用程序调用 select 函数时,通过这 3 个参数传入自己感兴趣的文件
描述符。select 返回时,内核将修改它们来通知应用程序哪些文件描述符已经就绪
fd_set 结构如下:#define __FD_SETSIZE 1024typedef long int __fd_mask;#define __NFDBITS (8 * (int) sizeof (__fd_mask))typedef struct{#ifdef __USE_XOPEN__fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];# define __FDS_BITS(set) ((set)->fds_bits)#else__fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS];# define __FDS_BITS(set) ((set)->__fds_bits)#endif} fd_set;通过下列宏可以访问 fd_set 结构中的位:FD_ZERO(fd_set *fdset); // 清除 fdset 的所有位FD_SET(int fd, fd_set *fdset); // 设置 fdset 的位 fdFD_CLR(int fd, fd_set *fdset); // 清除 fdset 的位 fdint FD_ISSET(int fd, fd_set *fdset);// 测试 fdset 的位 fd 是否被设置timeout 参数用来设置 select 函数的超时时间。它是一个 timeval 结构类型的指针,采用指针参数是因为内核将修改它以告诉应用程序 select 等待了多久。timeval结构的定义如下:struct timeval{long tv_sec; //秒数long tv_usec; // 微秒数};//struct timeval tv = {5,0};如果给 timeout 的两个成员都是 0,则 select 将立即返回。如果 timeout 传递
NULL,则 select 将一直阻塞,直到某个文件描述符就绪*/ 2.设计思路图解

3.测试代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/select.h>
#include<time.h>#define STDIN 0
int main()
{int fd = STDIN;//键盘fd_set fdset;//集合,收集描述符while(1)//因为不止检测一次{FD_ZERO(&fdset);//清空集合,每个位置0:FD_ZEROFD_SET(fd,&fdset);//将描述符fd添加到集合fdsetstruct timeval tv = {5,0};//超时时间int n = select(fd+1,&fdset,NULL,NULL,&tv);//可能阻塞if(n ==-1)//select执行失败{printf("select err\n");}else if(n==0)//超市,没有找到可用事件描述符{printf("tme out\n");}else{if(FD_ISSET(fd,&fdset)){char buff[128]={0};int num = read(fd,buff,127);printf("num=%d,buff=%s\n",num,buff);}}}
}
~
~
~ 4.tcp通过select实现并发连接
SER.C
#include<stdio.h> // 标准输入输出库
#include<stdlib.h> // 标准库,提供一些函数如malloc, free, rand等
#include<string.h> // 字符串操作库
#include<unistd.h> // UNIX标准函数库
#include<sys/select.h>// 选择库,提供select函数
#include<time.h> // 时间库
#include<sys/socket.h>// 套接字库
#include<arpa/inet.h> // 提供inet_addr等函数
#include<netinet/in.h>// 提供一些网络相关的宏#define MAXFD 10 // 定义最大文件描述符数量// 初始化socket函数
int socket_init();// 初始化文件描述符数组
void fds_init(int fds[]){for(int i=0; i<MAXFD; i++){fds[i] = -1; // 将所有文件描述符初始化为-1,表示未被使用}
}// 将新的文件描述符添加到数组中
void fds_add(int fds[], int fd){for(int i=0; i<MAXFD; i++){if(fds[i] == -1){ // 找到数组中第一个未使用的文件描述符位置fds[i] = fd; // 添加文件描述符break; // 退出循环}}
}// 从未使用的文件描述符数组中删除指定的文件描述符
void fds_del(int fds[], int fd){for(int i=0; i<MAXFD; i++){if(fds[i] == fd){ // 找到要删除的文件描述符fds[i] = -1; // 将其设置为-1,表示未使用break; // 退出循环}}
}// 接受客户端连接请求并添加到文件描述符数组
void accept_client(int sockfd, int fds[]){int c = accept(sockfd, NULL, NULL); // 接受连接if(c < 0){return; // 如果返回-1,表示出错}printf("accept c = %d\n", c);fds_add(fds, c); // 添加到文件描述符数组
}// 接收客户端发送的数据
void recv_date(int c, int fds[]){char buff[128] = {0}; // 创建缓冲区int n = recv(c, buff, 127, 0); // 接收数据if(n < 0){printf("cli close\n");close(c); // 如果接收失败,关闭连接fds_del(fds, c); // 从数组中删除该文件描述符return;}if(n == 0){printf("time out(%d)\n", n); // 如果超时}printf("buff(c=%d)=%s\n", c, buff); // 打印接收到的数据send(c, "ok", 2, 0); // 发送确认消息
}// 主函数
int main(){int sockfd = socket_init(); // 初始化socketif(sockfd == -1){exit(1); // 如果初始化失败,退出程序}int fds[MAXFD]; // 文件描述符数组fds_init(fds); // 初始化数组fds_add(fds, sockfd); // 将监听的socket添加到数组fd_set fdset; // 创建文件描述符集合while(1){ // 无限循环等待事件FD_ZERO(&fdset); // 清空文件描述符集合int maxfd = -1; // 存储最大的文件描述符// 遍历文件描述符数组,将所有文件描述符添加到集合中for(int i=0; i<MAXFD; i++){if(fds[i] == -1){continue; // 如果文件描述符未使用,跳过}FD_SET(fds[i], &fdset); // 添加到集合if(fds[i] > maxfd){ // 更新最大文件描述符maxfd = fds[i];}}struct timeval tv = {5,0}; // 设置超时时间// 使用select等待直到有文件描述符准备好IO操作或超时int n = select(maxfd+1, &fdset, NULL, NULL, &tv);if(n == -1){printf("select err\n"); // 错误} else if(n == 0){printf("time out\n"); // 超时} else{// 遍历文件描述符数组,检查哪些文件描述符准备好了IO操作for(int i=0; i<MAXFD; i++){if(fds[i] == -1){continue; // 如果文件描述符未使用,跳过}if(FD_ISSET(fds[i], &fdset)){ // 检查文件描述符是否被设置if(fds[i] == sockfd){ // 如果是监听的socketaccept_client(sockfd, fds); // 接受新的连接} else{ // 如果是已连接的客户端recv_date(fds[i], fds); // 接收数据}}}}}
}// 创建socket并绑定到端口
int socket_init(){int sockfd = socket(AF_INET, SOCK_STREAM, 0); // 创建socketif(sockfd == -1){return -1; // 创建失败返回-1}struct sockaddr_in saddr; // 服务器地址结构memset(&saddr, 0, sizeof(saddr)); // 清零saddr.sin_family = AF_INET; // 地址族saddr.sin_port = htons(6000); // 端口saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // IP地址int res = bind(sockfd, (struct sockaddr*)&saddr, sizeof(saddr)); // 绑定if(res == -1){printf("bind err\n");return -1; // 绑定失败返回-1}if(listen(sockfd, 5) == -1){ // 开始监听,设置队列长度为5return -1; // 监听失败返回-1}return sockfd; // 返回socket文件描述符
} CLI.C
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>int main()
{int sockfd = socket(AF_INET,SOCK_STREAM,0);if(sockfd == -1){exit(1);}struct sockaddr_in saddr;//代表服务器的端口memset(&saddr,0,sizeof(saddr));saddr.sin_family = AF_INET;saddr.sin_port = htons(6000);saddr.sin_addr.s_addr = inet_addr("127.0.0.1");int res = connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));if(res == -1){printf("connct err\n");exit(1);}while(1){printf("input: ");char buff[128]={0};fgets(buff,128,stdin);if(strncmp(buff,"end",3)==0){break;}send(sockfd,buff,strlen(buff)-1,0);memset(buff,0,128);recv(sockfd,buff,127,0);printf("buff=%s\n",buff);}close(sockfd);exit(0);
} 相关文章:
26-LINUX--I/O复用-select
一.I/O复用概述 /O复用使得多个程序能够同时监听多个文件描述符,对提高程序的性能有很大帮助。以下情况适用于I/O复用技术: ◼ TCP 服务器同时要处理监听套接字和连接套接字。 ◼ 服务器要同时处理 TCP 请求和 UDP 请求。 ◼ 程序要同时处理多个套接…...
spring源码解析-(2)Bean的包扫描
包扫描的过程 测试代码: // 扫描指定包下的所有类 BeanDefinitionRegistry registry new SimpleBeanDefinitionRegistry(); // 扫描指定包下的所有类 ClassPathBeanDefinitionScanner scanner new ClassPathBeanDefinitionScanner(registry); scanner.scan(&quo…...
Java 数学计算 - Random类
在Java中,Random类用于生成伪随机数。这个类在java.util包中,你可以使用它来生成整数、浮点数等不同类型的随机数。以下是关于Random类的一些学习笔记和示例。 1. 创建Random对象 首先,你需要创建一个Random对象。默认情况下,如…...
Ubuntu22.04之解决:无法关机和重启问题(二百四十三)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…...
大学数字媒体艺术设计网页设计试题及答案,分享几个实用搜题和学习工具 #媒体#职场发展
现在读书可不像小时候,以前想要校对试题答案,都得找到对应的纸质版答案查看,而且有的还只有答案,没有解析,无法弄清楚答案的由来。但是现在不一样了,现在我们可以通过搜题软件,寻找试题的答案&a…...
【ArcGIS微课1000例】0119:TIFF与grid格式互相转换
文章目录 一、任务描述二、tiff转grid三、grid转tif四、注意事项一、任务描述 地理栅格数据常用TIFF格式和GRID格式进行存储。TIFF格式的栅格数据常以单文件形式存储,不仅存储有R、G、B三波段的像素值,还保存有地理坐标信息。GRID格式的栅格数据常以多文件的形式进行存储,且…...
B3870 [GESP202309 四级] 变长编码
[GESP202309 四级] 变长编码 题目描述 小明刚刚学习了三种整数编码方式:原码、反码、补码,并了解到计算机存储整数通常使用补码。但他总是觉得,生活中很少用到 2 31 − 1 2^{31}-1 231−1 这么大的数,生活中常用的 0 ∼ 100 0…...
WordPress网站更换域名后如何重新激活elementor
在创建WordPress网站时,我们常常需要更改域名。但是,在更换域名后,你可能会遇到一个问题:WordPress后台中的Elementor插件授权状态会显示为不匹配。这时,就需要重新激活Elementor插件的授权。下面我会详细说明如何操作…...
linux cron 执行url
linux cron 执行url 在Linux中,你可以使用curl或wget来执行URL。如果你想要定期执行这个操作,可以使用cron来设置定时任务。 以下是一个使用curl在cron中执行URL的例子: 打开终端。 输入 crontab -e 命令来编辑你的cron作业。 添加一个新…...
压缩视频在线压缩网站,压缩视频在线压缩工具软件
在数字化时代,视频成为了人们记录和分享生活的重要载体。然而,视频文件一般都非常大,这不仅占据了大量的存储空间,也给视频的传输和分享带来了不便。因此,压缩视频成为了许多人必须掌握的技能。本文将详细介绍如何压缩…...
linux经典例题编程
编写Shell脚本,计算1~100的和 首先vi 1.sh,创建一个名为1.sh的脚本,然后赋予这个脚本权限,使用命令chmod 755 1.sh,然后就可以在脚本中写程序,然后运行。 shell脚本内容 运行结果: 编写Shell脚本…...
二叉树的实现(初阶数据结构)
1.二叉树的概念及结构 1.1 概念 一棵二叉树是结点的一个有限集合,该集合: 1.或者为空 2.由一个根结点加上两棵别称为左子树和右子树的二叉树组成 从上图可以看出: 1.二叉树不存在度大于2的结点 2.二叉树的子树有左右之分,次序不能…...
C++笔试强训day41
目录 1.棋子翻转 2.宵暗的妖怪 3.过桥 1.棋子翻转 链接https://www.nowcoder.com/practice/a8c89dc768c84ec29cbf9ca065e3f6b4?tpId128&tqId33769&ru/exam/oj (简单题)对题意进行简单模拟即可: class Solution { public:int dx[…...
【JavaScript】内置对象 - 字符串对象 ⑤ ( 判断对象中是否有某个属性 | 统计字符串中每个字符出现的次数 )
文章目录 一、判断对象中是否有某个属性1、获取对象属性2、判定对象是否有某个属性 二、统计字符串中每个字符出现的次数1、算法分析2、代码示例 String 字符串对象参考文档 : https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String 一、判…...
Linux环境下测试服务器的DDR5内存性能
要在Linux环境下测试服务器的DDR5内存性能,可以采用以下几种方法和工具: ### 测试原理 内存性能测试主要关注以下几个关键指标: - **带宽**:内存每秒能传输的数据量。 - **延迟**:内存访问请求从发出到完成所需的时间…...
19、matlab信号预处理中的中值滤波(medfilt1()函数)和萨维茨基-戈雷滤波滤(sgolayfilt()函数)
1、中值滤波:medfilt1()函数 说明:一维中值滤波 1)语法 语法1:y medfilt1(x) 将输入向量x应用3阶一维中值滤波器。 语法2:y medfilt1(x,n) 将一个n阶一维中值滤波器应用于x。 语法3:y medfilt1(x,n…...
Scala 练习一 将Mysql表数据导入HBase
Scala 练习一 将Mysql表数据导入HBase 续第一篇:Java代码将Mysql表数据导入HBase表 源码仓库地址:https://gitee.com/leaf-domain/data-to-hbase 一、整体介绍二、依赖三、测试结果四、源码 一、整体介绍 HBase特质 连接HBase, 创建HBase执行对象 初始化…...
前端工程化:基于Vue.js 3.0的设计与实践
这里写目录标题 《前端工程化:基于Vue.js 3.0的设计与实践》书籍引言本书概述主要内容作者简介为什么选择这本书?结语 《前端工程化:基于Vue.js 3.0的设计与实践》书籍 够买连接—>https://item.jd.com/13952512.html 引言 在前端技术日…...
Linux☞进程控制
在终端执行命令时,Linux会建立进程,程序执行完,进程会被终止;Linux是一个多任务的OS,允许多个进程并发运行; Linxu中启动进程的两种途径: ①手动启动(前台进程(命令gedit)...后台进程(命令‘&’)) ②…...
mybatis离谱bug乱转类型
字符串传入的参数被转成了int: Param("online") String online<if test"online 0">and (heart_time is null or heart_time <![CDATA[ < ]]> UNIX_TIMESTAMP(SUBDATE(now(),INTERVAL 8 MINUTE)) )</if><if test"…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...
提升移动端网页调试效率:WebDebugX 与常见工具组合实践
在日常移动端开发中,网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时,开发者迫切需要一套高效、可靠且跨平台的调试方案。过去,我们或多或少使用过 Chrome DevTools、Remote Debug…...
TJCTF 2025
还以为是天津的。这个比较容易,虽然绕了点弯,可还是把CP AK了,不过我会的别人也会,还是没啥名次。记录一下吧。 Crypto bacon-bits with open(flag.txt) as f: flag f.read().strip() with open(text.txt) as t: text t.read…...
FTXUI::Dom 模块
DOM 模块定义了分层的 FTXUI::Element 树,可用于构建复杂的终端界面,支持响应终端尺寸变化。 namespace ftxui {...// 定义文档 定义布局盒子 Element document vbox({// 设置文本 设置加粗 设置文本颜色text("The window") | bold | color(…...
