多路转接之select(fd_set介绍,参数详细介绍),实现非阻塞式网络通信
目录
多路转接之select
引入
介绍
fd_set
函数原型
nfds
readfds / writefds / exceptfds
readfds
总结
fd_set操作接口
timeout
timevalue 结构体
传入值
返回值
代码
注意点 -- 调用函数
select的参数填充
获取新连接
注意点 -- 通信时的调用函数
添加新fd到位图中
处理函数
多路转接之select
引入
io本质+io效率本质,5种io模型(介绍,异步/同步区别,阻塞/非阻塞区别)-CSDN博客
以前使用的io接口,既完成等待,又完成拷贝
但在多路转接的io方式中不同,分为两个部分,需要调用两个函数来完成
介绍
select只负责等待,一次可以等待多个fd
- 就像之前钓鱼例子中的d,他拥有多个鱼竿,就相当于等待多个fd
既然可以关注多个fd,自然参数中就要使用其他数据结构了 -- fd_set
fd_set
内核提供的一种数据类型
- 位图
因为fd_set是一个具体的类型
- 既然是类型,就一定有大小
- 有大小就会有比特位的数量
- 也就相当于可以等待的文件fd值和文件数量是有上限的
使用sizeof测试fd_set的大小,得到它是1024个bit
- 所以一次最多等待1024个文件的某个事件
- 这个值随着系统不同会有变化,实际应该动态计算 -- sizeof(fd_set) * 8
函数原型

nfds
要等待的多个fd中的最大值+1
readfds / writefds / exceptfds
等待多个fd的关键,属于输入输出型参数
等待 -- 等待事件就绪
- 事件 -- 一般分为 读/写/有异常
- 只要读写事件就绪,就可以直接完成拷贝操作,不会阻塞住
- 异常事件是例外,需要特殊处理,这里不做介绍
如果想关注某个文件上的读事件,就把该文件的fd设置进readfds
- 其他同理
- 可以关注同一个文件上的多个事件,也可以分顺序地关注,总之设置进相应位图中就行
接下来我们以readfds为例,详细介绍一下,其他位图同理
readfds
fd本身就是从0开始的数字
- 和数组下标/位图均可以一一对应
因为是输入输出型参数:
输入时
- 我们要告诉内核需要关注的fd集,你要帮我关心这些文件上面的读事件 + 这是个位图结构 + fd和位图可以对应
- 所以,可以得出,位图上的比特位位置(从左向右,从0开始) 对应 文件的fd值
- 只要该位设置为1,就是我们想让内核关注该文件
- eg:我们要关注0,1,2,3这四个文件:
输出时
- 内核要告诉我们,关注的fd集中有哪些fd上的读事件已经就绪 + 返回的也是个位图结构
- 所以,对应关系依然没有变,但代表的含义不同
- 如果该位为1,说明该文件上的读事件已经就绪
- 内核会先将位图清零,然后将[读事件已经就绪的文件]的fd值 对应的 比特位 置1
- eg:四个文件中,fd=2的文件的读事件就绪:
总结
所以,总结来说,fd_set这张位图,是让用户和内核之间互相传递信息的
- 那么,在使用select函数的过程中,一定会涉及大量的位图操作
fd_set操作接口
为了让用户更方便,内核为我们提供了接口
timeout
设置select的等待方式
每隔若干秒,timeout一次,timeout后 / 有文件就绪后函数会返回
timevalue 结构体
在gettimeofday()中也有使用这个类型作为参数:
- 获取特定时区下的特定时间,精确到微秒级别
- 时间戳 -- 秒单位和微妙单位
- 比如传入参数{5,0},代表设置时间戳为5s
传入值
- 设置>0 -- 每隔一段时间timeout一次,比如5s
- 设置为0 -- 非阻塞(select立即返回)
- 设置为NULL -- 阻塞等待,直到有文件就绪
如果设置(非NULL)了该时间
- 则为输入输出型参数
- 如果在等待的中途有文件就绪,则返回[timeout时间-已经等待时间],也就是[距离超时时间的剩余时间 ]
返回值
- >0 -- 有n个fd就绪
- =0 -- 超时,等待过程中没有错误,也没有fd就绪
- <0 -- 等待出错(要等待的某个文件已经关闭了)
代码
我们这里实现一个非阻塞版网络通信
注意点 -- 调用函数
创建好套接字后,不能直接accept
- accept本质就是在检测并获取listensock上面的事件
- 但我们这里目的就是要让select去等待事件(有事件了再去通知我们来获取,这时候调用accept就不会被阻塞了)
- 所以不能先调用accept
这里的事件:
- = 新连接到来 = 三次握手完成,系统把新连接投递到全连接队列里 = select里的读事件
- 所以我们先调用select等待读事件
select的参数填充
这里是服务器刚启动时,是我们需要让listensocket检测并获取新连接(新客户端与当前服务器通信)
- 所以,等待的是listensocket上的读事件,并且当前只有这一个套接字
- 所以,max_fd=listensocket_fd+1
- 等有客户端连接后,会有新的套接字被创建(通信时使用的套接字),就需要添加检测这些套接字上的读写事件了(后面会细说)
因为timeout是输入输出型参数
- 一旦超时/当前有事件就绪,就会修改timeout的值
- 所以,为了不影响下一次的等待方式,需要重复设置timeout参数
三个位图集也是同理,需要重复设置
- 不然会被修改成已经就绪的,而不代表需要内核关注的fd集
获取新连接
如果事件就绪,上层却不处理,select会一直通知
- 所以需要我们手动调用accept()去把新连接拿走(这个操作在我们新的处理函数中)
当然,我们无法确定是哪个fd就绪了
- 所以需要先判断
- 判断完成后,就可以拿到新连接,创建新套接字了
注意点 -- 通信时的调用函数
接下来要开始通信了,原先我们的服务器是直接read,但这里不行
- 因为read是阻塞式等待,而我们要实现非阻塞式
- 而且一旦阻塞在这里,就无法获取新连接以及与其他客户端通信了(因为我们写的是单进程)
- 所以,还是需要使用select
添加新fd到位图中
当然,我们不能调用新的select
- 为什么?
- 一般都是在主循环处持续调用select,高效且简洁
- 如果使用多个select,会导致代码逻辑复杂化,也难以管理
所以,需要我们把这个新套接字的fd设置进刚才的select的位图中
- 这一过程就相当于d在不断增加自己鱼竿的数量
但是,这两个数据在不同的函数中(我们在处理函数中获取新连接,而select的使用在主逻辑函数中),如何传递呢?
- 因为这两个函数都在类中,所以我们搞一个类内变量 -- 辅助数组
- 让新增的fd都添加进辅助数组中,然后让select每次动态设置max_fd,以及三个位图
可以固定监听套接字(也就是我们创建的第一个套接字)作为数组的第一项
- 方便我们后续区分[获取新连接] 和 [读写事件]
因为在过程中,可能会陆陆续续关掉一些文件
- 所以原本添加进的连续fd,会变成零零星星的
- 所以,需要我们每次都重新整理一下这个数组,把有效的fd统一放在左侧
我们每次在循环开头就处理数组中的值
- 合法的fd就让它设置进位图中
- 不仅如此,在这个过程中,我们还可以找到fd中的最大值,来填充select参数
解决了如何添加新fd的问题,接下来回到处理函数
处理函数
当我们识别到有事件就绪,获取连接后获得新套接字fd,之后就该将该fd设置进辅助数组中了
- 需要我们遍历数组,找到空位(值为-1/其他你设定的[数组内的初始值]),然后添加进去
更新ing...
相关文章:
多路转接之select(fd_set介绍,参数详细介绍),实现非阻塞式网络通信
目录 多路转接之select 引入 介绍 fd_set 函数原型 nfds readfds / writefds / exceptfds readfds 总结 fd_set操作接口 timeout timevalue 结构体 传入值 返回值 代码 注意点 -- 调用函数 select的参数填充 获取新连接 注意点 -- 通信时的调用函数 添…...
乐鑫安全制造全流程
主要参考资料: 【乐鑫全球开发者大会】DevCon24 #10 |乐鑫安全制造全流程 乐鑫官方文档Flash加密: https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/security/flash-encryption.html 【ESP32S3】使用 Flash 下载工具完成 Flash 加密功能…...
〖open-mmlab: MMDetection〗解析文件:configs/_base_/schedules
详细解析三个训练调度文件:schedule_1x.py、schedule_2x.py、schedule_20e.py 在深度学习模型训练过程中,训练调度(Training Schedule)是至关重要的,它决定了模型训练过程中学习率(Learning Rate, LR&…...
Android之Handler是如何保证延迟发送的
目录 核心组件延迟发送消息的工作原理具体步骤1. 创建 Handler:2.发送延迟消息3.消息入队列4.消息出队和处理: 关键点总结 在 Android 中,Handler 是用于在不同线程之间传递和处理消息的工具。它可以用于定时任务、延迟执行任务等。Handler 如何保证延迟发送消息的核…...
定位信标、基站、标签,定位信标是什么
定位信标、基站、标签,定位信标是什么 今天给各位分享定位信标、基站、标签的知识,其中也会对定位信标是什么进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧! 怎样做人员定位啊? 〖…...
2024国赛数学建模B题完整分析参考论文38页(含模型和可运行代码)
2024 高教社杯全国大学生数学建模完整分析参考论文 B 题 生产过程中的决策问题 目录 摘要 一、问题重述 二、问题分析 三、 模型假设 四、 模型建立与求解 4.1问题1 4.1.1问题1思路分析 4.1.2问题1模型建立 4.1.3问题1样例代码(仅供参考) 4.…...
Hive是什么?
Apache Hive 是一个基于 Hadoop 的数据仓库工具,用于在 Hadoop 分布式文件系统(HDFS)上管理和查询大规模结构化数据集。Hive 提供了一个类似 SQL 的查询语言,称为 HiveQL,通过这种语言可以在 HDFS 上执行 MapReduce 作…...
计算机网络:http协议
计算机网络:http协议 一、本文内容与前置知识点1. 本文内容2. 前置知识点 二、HTTP协议工作简介1. 特点2. 传输时间分析3. http报文结构 三、HTTP版本迭代1. HTTP1.0和HTTP1.1主要区别2. HTTP1.1和HTTP2主要区别3. HTTPS与HTTP的主要区别 四、参考文献 一、本文内容…...
【stata】自写命令分享dynamic_est,一键生成dynamic effect
1. 命令简介 dynamic_est 是一个用于可视化动态效应(dynamic effect)的工具。它特别适用于事件研究(event study)或双重差分(Difference-in-Differences, DID)分析。通过一句命令即可展示动态效应…...
文心一言 VS 讯飞星火 VS chatgpt (342)-- 算法导论23.2 1题
一、对于同一个输入图,Kruskal算法返回的最小生成树可以不同。这种不同来源于对边进行排序时,对权重相同的边进行的不同处理。证明:对于图G的每棵最小生成树T,都存在一种办法来对G的边进行排序,使得Kruskal算法所返回的…...
部署若依Spring boot项目
nohup和& nohup命令解释 nohup命令:nohup 是 no hang up 的缩写,就是不挂断的意思,但没有后台运行,终端不能标准输入。 nohup :不挂断的运行,注意并没有后台运行的功能,就是指,用nohup运行命令可以使命令永久的执行下去,和用户终端没有关系,注意了nohup没有后台…...
oc打包:权限弹窗无法正常弹出
在遇到编写了权限无法弹出弹窗时,需要查看是不是调用时机不对,这里直接教万能改法。 将权限获取方法编写在applicationDidBecomeActive 进入前台的生命周期接口中,如下: if (@available(iOS 14, *)) {NSLog<...
深入理解RxJava:响应式编程的现代方式
在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJ…...
Maven 依赖漏洞扫描检查插件 dependency-check-maven 的使用
前言 在现代软件开发中,开源库的使用愈加普遍,然而这些开源库中的漏洞往往会成为潜在的安全风险。如何及时的发现依赖的第三方库是否存在漏洞,就变成很重要了。 本文向大家推荐一款可以进行依赖包漏洞检查的 maven 插件 dependency-check-m…...
2. 下载rknn-toolkit2项目
官网链接: https://github.com/airockchip/rknn-toolkit2 安装好git:[[1. Git的安装]] 下载项目: git clone https://github.com/airockchip/rknn-toolkit2.git或者直接去github下载压缩文件,解压即可。...
xhr、ajax、axois、fetch的区别
一、XMLHttpRequest (XHR)、AJAX、Axios 和 Fetch API 都是用于在不重新加载整个页面的情况下与服务器进行通信的技术和库。它们在处理超时、终止请求、进度反馈等机制上有一些显著的差异。以下是它们的详细比较: 1. XMLHttpRequest (XHR) XMLHttpRequest 是一种浏…...
【HuggingFace Transformers】OpenAIGPTModel源码解析
OpenAIGPTModel源码解析 1. GPT 介绍2. OpenAIGPTModel类 源码解析 说到ChatGPT,大家可能都使用过吧。2022年,ChatGPT的推出引发了广泛的关注和讨论。这款对话生成模型不仅具备了强大的语言理解和生成能力,还能进行非常自然的对话,…...
macOS安装Java和Maven
安装Java Java Downloads | Oracle 官网下载默认说最新的Java22版本,注意这里我们要下载的是Java8,对应的JDK1.8 需要登陆Oracle,没有账号的可以百度下。账号:908344069qq.com 密码:Java_2024 Java8 jdk1.8配置环境变量 open -e ~/.bash_p…...
SpringBoot教程(安装篇) | Elasticsearch的安装
SpringBoot教程(安装篇) | Elasticsearch的安装 一、确定Elasticsearch版本二、下载elasticsearch(windows版本)官网下载如何解压配置 允许 别人跨域 访问自己启动运行 三、Es可视化工具安装(elasticsearch-head&#…...
前端登录鉴权——以若依Ruoyi前后端分离项目为例解读
权限模型 Ruoyi框架学习——权限管理_若依框架权限-CSDN博客 用户-角色-菜单(User-Role-Menu)模型是一种常用于权限管理的设计模式,用于实现系统中的用户权限控制。该模型主要包含以下几个要素: 用户(User)…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
jdbc查询mysql数据库时,出现id顺序错误的情况
我在repository中的查询语句如下所示,即传入一个List<intager>的数据,返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致,会导致返回的id是从小到大排列的,但我不希望这样。 Query("SELECT NEW com…...




