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

多路转接之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的参数填充 获取新连接 注意点 -- 通信时的调用函数 添…...

乐鑫安全制造全流程

主要参考资料&#xff1a; 【乐鑫全球开发者大会】DevCon24 #10 &#xff5c;乐鑫安全制造全流程 乐鑫官方文档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

详细解析三个训练调度文件&#xff1a;schedule_1x.py、schedule_2x.py、schedule_20e.py 在深度学习模型训练过程中&#xff0c;训练调度&#xff08;Training Schedule&#xff09;是至关重要的&#xff0c;它决定了模型训练过程中学习率&#xff08;Learning Rate, LR&…...

Android之Handler是如何保证延迟发送的

目录 核心组件延迟发送消息的工作原理具体步骤1. 创建 Handler:2.发送延迟消息3.消息入队列4.消息出队和处理: 关键点总结 在 Android 中&#xff0c;Handler 是用于在不同线程之间传递和处理消息的工具。它可以用于定时任务、延迟执行任务等。Handler 如何保证延迟发送消息的核…...

定位信标、基站、标签,定位信标是什么

定位信标、基站、标签&#xff0c;定位信标是什么 今天给各位分享定位信标、基站、标签的知识&#xff0c;其中也会对定位信标是什么进行解释&#xff0c;如果能碰巧解决你现在面临的问题&#xff0c;别忘了关注本站&#xff0c;现在开始吧&#xff01; 怎样做人员定位啊? 〖…...

2024国赛数学建模B题完整分析参考论文38页(含模型和可运行代码)

2024 高教社杯全国大学生数学建模完整分析参考论文 B 题 生产过程中的决策问题 目录 摘要 一、问题重述 二、问题分析 三、 模型假设 四、 模型建立与求解 4.1问题1 4.1.1问题1思路分析 4.1.2问题1模型建立 4.1.3问题1样例代码&#xff08;仅供参考&#xff09; 4.…...

Hive是什么?

Apache Hive 是一个基于 Hadoop 的数据仓库工具&#xff0c;用于在 Hadoop 分布式文件系统&#xff08;HDFS&#xff09;上管理和查询大规模结构化数据集。Hive 提供了一个类似 SQL 的查询语言&#xff0c;称为 HiveQL&#xff0c;通过这种语言可以在 HDFS 上执行 MapReduce 作…...

计算机网络:http协议

计算机网络&#xff1a;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 是一个用于可视化动态效应&#xff08;dynamic effect&#xff09;的工具。它特别适用于事件研究&#xff08;event study&#xff09;或双重差分&#xff08;Difference-in-Differences, DID&#xff09;分析。通过一句命令即可展示动态效应&#xf…...

文心一言 VS 讯飞星火 VS chatgpt (342)-- 算法导论23.2 1题

一、对于同一个输入图&#xff0c;Kruskal算法返回的最小生成树可以不同。这种不同来源于对边进行排序时&#xff0c;对权重相同的边进行的不同处理。证明&#xff1a;对于图G的每棵最小生成树T&#xff0c;都存在一种办法来对G的边进行排序&#xff0c;使得Kruskal算法所返回的…...

部署若依Spring boot项目

nohup和& nohup命令解释 nohup命令:nohup 是 no hang up 的缩写,就是不挂断的意思,但没有后台运行,终端不能标准输入。 nohup :不挂断的运行,注意并没有后台运行的功能,就是指,用nohup运行命令可以使命令永久的执行下去,和用户终端没有关系,注意了nohup没有后台…...

oc打包:权限弹窗无法正常弹出

在遇到编写了权限无法弹出弹窗时,需要查看是不是调用时机不对,这里直接教万能改法。 将权限获取方法编写在applicationDidBecomeActive 进入前台的生命周期接口中,如下: if (@available(iOS 14, *)) {NSLog<...

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中&#xff0c;异步编程和事件驱动的架构变得越来越重要。RxJava&#xff0c;作为响应式编程&#xff08;Reactive Programming&#xff09;的一个流行库&#xff0c;为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJ…...

Maven 依赖漏洞扫描检查插件 dependency-check-maven 的使用

前言 在现代软件开发中&#xff0c;开源库的使用愈加普遍&#xff0c;然而这些开源库中的漏洞往往会成为潜在的安全风险。如何及时的发现依赖的第三方库是否存在漏洞&#xff0c;就变成很重要了。 本文向大家推荐一款可以进行依赖包漏洞检查的 maven 插件 dependency-check-m…...

2. 下载rknn-toolkit2项目

官网链接&#xff1a; https://github.com/airockchip/rknn-toolkit2 安装好git&#xff1a;[[1. Git的安装]] 下载项目&#xff1a; git clone https://github.com/airockchip/rknn-toolkit2.git或者直接去github下载压缩文件&#xff0c;解压即可。...

xhr、ajax、axois、fetch的区别

一、XMLHttpRequest (XHR)、AJAX、Axios 和 Fetch API 都是用于在不重新加载整个页面的情况下与服务器进行通信的技术和库。它们在处理超时、终止请求、进度反馈等机制上有一些显著的差异。以下是它们的详细比较&#xff1a; 1. XMLHttpRequest (XHR) XMLHttpRequest 是一种浏…...

【HuggingFace Transformers】OpenAIGPTModel源码解析

OpenAIGPTModel源码解析 1. GPT 介绍2. OpenAIGPTModel类 源码解析 说到ChatGPT&#xff0c;大家可能都使用过吧。2022年&#xff0c;ChatGPT的推出引发了广泛的关注和讨论。这款对话生成模型不仅具备了强大的语言理解和生成能力&#xff0c;还能进行非常自然的对话&#xff0c…...

macOS安装Java和Maven

安装Java Java Downloads | Oracle 官网下载默认说最新的Java22版本&#xff0c;注意这里我们要下载的是Java8&#xff0c;对应的JDK1.8 需要登陆Oracle&#xff0c;没有账号的可以百度下。账号:908344069qq.com 密码:Java_2024 Java8 jdk1.8配置环境变量 open -e ~/.bash_p…...

SpringBoot教程(安装篇) | Elasticsearch的安装

SpringBoot教程&#xff08;安装篇&#xff09; | Elasticsearch的安装 一、确定Elasticsearch版本二、下载elasticsearch&#xff08;windows版本&#xff09;官网下载如何解压配置 允许 别人跨域 访问自己启动运行 三、Es可视化工具安装&#xff08;elasticsearch-head&#…...

前端登录鉴权——以若依Ruoyi前后端分离项目为例解读

权限模型 Ruoyi框架学习——权限管理_若依框架权限-CSDN博客 用户-角色-菜单&#xff08;User-Role-Menu&#xff09;模型是一种常用于权限管理的设计模式&#xff0c;用于实现系统中的用户权限控制。该模型主要包含以下几个要素&#xff1a; 用户&#xff08;User&#xff09;…...

OpenSSH ssh-agent动态链接劫持漏洞CVE-2023-38408深度修复指南

1. 这不是一次普通升级&#xff1a;CVE-2023-38408为什么必须亲手编译修复 OpenSSH-ssh-agent CVE-2023-38408——这个编号在2023年7月刚披露时&#xff0c;很多运维和安全工程师第一反应是“又一个高危漏洞”&#xff0c;点开NVD页面扫一眼CVSS 8.8分&#xff0c;记下补丁版本…...

谷歌内部CSR策划SOP首次流出(非公开版):含风险预判矩阵、利益相关方触达热力图与监管审计应答话术库

更多请点击&#xff1a; https://codechina.net 第一章&#xff1a;Gemini CSR活动策划的底层逻辑与战略定位 Gemini CSR&#xff08;Corporate Social Responsibility&#xff09;活动并非孤立的品牌传播动作&#xff0c;而是深度嵌入企业技术价值观与长期可持续发展框架的战…...

5大AI音频处理插件:用OpenVINO为Audacity注入本地智能处理能力

5大AI音频处理插件&#xff1a;用OpenVINO为Audacity注入本地智能处理能力 【免费下载链接】openvino-plugins-ai-audacity A set of AI-enabled effects, generators, and analyzers for Audacity. 项目地址: https://gitcode.com/gh_mirrors/op/openvino-plugins-ai-audaci…...

基于 OAuth 设备码流滥用的 Kali365 钓鱼攻击机理与防御体系研究

摘要 2026 年 5 月&#xff0c;美国联邦调查局&#xff08;FBI&#xff09;发布安全预警&#xff0c;披露针对 Microsoft 365 环境的 PhaaS 平台 Kali365 正通过滥用 OAuth 设备码认证流程实施规模化钓鱼攻击&#xff0c;可绕过多因素认证&#xff08;MFA&#xff09;窃取合法访…...

【Gemini生命周期价值深度解码】:20年AI架构师亲授5大阶段ROI测算模型与避坑指南

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Gemini生命周期价值分析 Gemini 模型的生命周期价值&#xff08;LTV&#xff09;不仅体现在其推理性能与多模态能力上&#xff0c;更贯穿于从模型部署、持续微调、监控反馈到迭代升级的完整闭环。相较于…...

从 ROI 看:什么时候只用单 Agent 更优

从 ROI 看&#xff1a;什么时候只用单 Agent 更优一、 引言 (Introduction) 1.1 钩子 (The Hook) 你有没有见过这样的项目场景&#xff1f; 场景1&#xff1a;创业公司MVP阶段 小团队只有2个算法工程师、1个全栈&#xff0c;预算只有30万/月的云服务和人力折算&#xff08;算法…...

机器学习在犯罪关联分析中的应用:从原理到实战

1. 项目概述&#xff1a;当机器学习遇见犯罪关联分析干了十几年数据分析&#xff0c;从商业智能做到公共安全领域&#xff0c;我越来越觉得&#xff0c;技术真正的价值在于解决那些“人脑算不过来、人手理不清楚”的复杂问题。犯罪关联分析&#xff08;Crime Linkage Analysis&…...

融合模糊决策与ECSA优化的软件项目智能风险评估框架

1. 项目概述与核心价值在软件工程这个行当里摸爬滚打十几年&#xff0c;我见过太多项目因为对风险的“视而不见”或“束手无策”而走向失败。项目延期、预算超支、质量滑坡&#xff0c;这些问题的根源往往不是技术本身&#xff0c;而是对潜在威胁的评估和应对失当。传统的风险管…...

通达信ChanlunX缠论插件:3步实现自动化技术分析的终极指南

通达信ChanlunX缠论插件&#xff1a;3步实现自动化技术分析的终极指南 【免费下载链接】ChanlunX 缠中说禅炒股缠论可视化插件 项目地址: https://gitcode.com/gh_mirrors/ch/ChanlunX 还在为复杂的缠论分析而烦恼吗&#xff1f;ChanlunX通达信缠论插件正是您需要的解决…...

告别TeamViewer!在Ubuntu 22.04上安装向日葵远程控制的完整保姆级教程

告别TeamViewer&#xff01;在Ubuntu 22.04上安装向日葵远程控制的完整保姆级教程 远程协作已成为现代开发者和运维人员的日常刚需。当TeamViewer频繁弹出商业使用提醒或遭遇连接不稳定时&#xff0c;许多技术从业者开始寻找更轻量、更自由的替代方案。作为国内领先的远程控制…...