27-LINUX--I/O复用-poll

一.poll概述

poll是一个多路复用的I/O模型,一个进程监视多个文件描述符,当文件描述符就绪时,poll返回可读并做相应处理。

1.poll的模型

#include <poll.h>struct pollfd
{int fd;         //文件描述符short events;   //事件类型 short revents;  //实际发送事件
}int poll(struct pollfd *fds, nfds_t nfds, int timeout);/*poll 系统调用成功返回就绪文件描述符的总数,超时返回 0,失败返回-1nfds 参数指定被监听事件集合 fds 的大小。timeout 参数指定 poll 的超时值,单位是毫秒,timeout 为-1 时,poll 调用将永久
阻塞,直到某个事件发生,timeout 为 0 时,poll 调用将立即返回。

2.事件类型

二.测试代码

SER.C

#include<stdio.h>      // 标准输入输出库
#include<stdlib.h>     // 标准库,提供动态内存分配等
#include<string.h>    // 字符串操作库
#include<unistd.h>    // UNIX标准函数库,提供close函数等
#include<sys/socket.h>// 套接字库
#include<netinet/in.h> // 网络头文件,提供IPv4地址格式
#include<arpa/inet.h> // 网络地址转换库
#include<poll.h>      // poll系统调用#define MAXFD 10       // 定义最大的文件描述符数量// 初始化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文件描述符
}// 初始化pollfd数组
void fds_init(struct pollfd fds[]) {for (int i = 0; i < MAXFD; i++) {fds[i].fd = -1; // 文件描述符设置为-1,表示未使用fds[i].events = 0; // 事件掩码设置为0fds[i].revents = 0; // 事件返回掩码设置为0}
}// 将新的文件描述符添加到pollfd数组
void fds_add(struct pollfd fds[], int fd) {for (int i = 0; i < MAXFD; i++) {if (fds[i].fd == -1) {fds[i].fd = fd; // 设置文件描述符fds[i].events = POLLIN; // 设置感兴趣的事件为POLLINfds[i].revents = 0; // 重置事件返回掩码break; // 退出循环}}
}// 从未使用的pollfd数组中删除文件描述符
void fds_del(struct pollfd fds[], int fd) {for (int i = 0; i < MAXFD; i++) {if (fds[i].fd == fd) {fds[i].fd = -1; // 将文件描述符重置为-1fds[i].events = 0; // 重置事件掩码fds[i].revents = 0; // 重置事件返回掩码break; // 退出循环}}
}// 接受客户端连接请求并添加到pollfd数组
void accept_cli(int sockfd, struct pollfd fds[]) {int c = accept(sockfd, NULL, NULL); // 接受连接if (c < 0) {return; // 如果返回-1,表示出错}printf("accept c = %d\n", c);fds_add(fds, c); // 添加到pollfd数组
}// 接收客户端数据
void recv_data(int c, struct pollfd fds[]) {char buff[128] = {0}; // 创建接收缓冲区int n = recv(c, buff, 127, 0); // 接收数据if (n <= 0) {close(c); // 如果接收失败或客户端关闭连接,则关闭socketprintf("cli close = %d\n", c);fds_del(fds, c); // 从pollfd数组中删除该文件描述符return;}printf("buff(%d)=%s\n", c, buff); // 打印接收到的数据send(c, "ok", 2, 0); // 发送确认消息给客户端
}// 主函数
int main() {int sockfd = socket_init(); // 初始化socketif (sockfd == -1) {exit(1); // 如果初始化失败,退出程序}struct pollfd fds[MAXFD]; // 创建pollfd数组fds_init(fds); // 初始化数组fds_add(fds, sockfd); // 将监听的socket添加到数组while (1) { // 无限循环,等待事件int n = poll(fds, MAXFD, 5000); // 调用poll等待最多5000毫秒if (n == -1) { // 如果poll调用失败printf("poll err\n");} else if (n == 0) { // 如果超时printf("time out\n");} else { // 如果有事件发生for (int i = 0; i < MAXFD; i++) { // 遍历pollfd数组if (fds[i].fd == -1) { // 如果文件描述符未使用,跳过continue;}if (fds[i].revents & POLLIN) { // 如果有可读事件发生if (fds[i].fd == sockfd) { // 如果是监听的socketaccept_cli(sockfd, fds); // 接受新的客户端连接} else { // 如果是已连接的客户端recv_data(fds[i].fd, fds); // 接收数据}}}}}
}

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

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

相关文章

OpenAI新研究破解GPT-4大脑,分解1600万个特征打开“黑匣子”,Ilya 、Jan Leike也参与了!

6月7日凌晨&#xff0c;OpenAI在官网发布了一个新的研究成果&#xff0c;首次破解GPT-4的神经网络活动。通过改进大规模训练稀疏自动编码器将GPT-4的内部表示分解为 1600 万个特征。而且&#xff0c;前段时间离职的Ilya Sutskever、Jan Leike也是作者之一&#xff01; 这不是破…

将AIRNet集成到yolov8中,实现端到端训练与推理

AIRNet是一个图像修复网络,支持对图像进行去雾、去雨、去噪声的修复。其基于对比的退化编码器(CBDE),将各种退化类型统一到同一嵌入空间;然后,基于退化引导恢复网络(DGRN)将嵌入空间修复为目标图像。可以将AIRNet的输出与yolov8进行端到端集成,实现部署上的简化。 本博…

关于 Redis 中集群

哨兵机制中总结到&#xff0c;它并不能解决存储容量不够的问题&#xff0c;但是集群能。 广义的集群&#xff1a;只要有多个机器&#xff0c;构成了分布式系统&#xff0c;都可以称之为一个“集群”&#xff0c;例如主从结构中的哨兵模式。 狭义的集群&#xff1a;redis 提供的…

Django学习二:配置mysql,创建model实例,自动创建数据库表,对mysql数据库表已经创建好的进行直接操作和实验。

文章目录 前言一、项目初始化搭建1、创建项目&#xff1a;test_models_django2、创建应用app01 二、配置mysql三、创建model实例&#xff0c;自动创建数据库表1、创建对象User类2、执行命令 四、思考问题&#xff08;****&#xff09;1、是否会生成新表呢&#xff08;答案报错&…

React保姆级教学

React保姆级教学 一、创建第一个react项目二、JSX基本语法与react基础知识1、 插值语法&#xff1a;2、 循环一个简单列表3、 实现简单条件渲染4、 实现复杂的条件渲染5、 事件绑定6、 基础组件&#xff08;函数组件&#xff09;7、 使用useState8、 基础样式控制9、 动态类名1…

好书推荐之《生成式 AI 入门与亚马逊云科技AWS实战》

最近小李哥在亚马逊云科技峰会领到了一本关于如何在云计算平台上设计、开发GenAI应用的书&#xff0c;名字叫&#xff1a;《生成式 AI 入门与亚马逊云科技AWS实战》&#xff0c;今天仔细看了下&#xff0c;发现这本书讲的真的很好&#xff01;他涵盖了当下AI领域所有热门的技术…

《软件定义安全》之四:什么是软件定义安全

第4章 什么是软件定义安全 1.软件定义安全的含义 1.1 软件定义安全的提出 虚拟化、云计算、软件定义架构的出现&#xff0c;对安全体系提出了新的挑战。如果要跟上网络演进的步伐和业务快速创新的速度&#xff0c;安全体系应该朝以下方向演变。 &#x1d7ed; 安全机制软件…

设计软件有哪些?照明工具篇,渲染100邀请码1a12

阴影和照明涉及到图片的真实感和氛围&#xff0c;所以熟练使用照明工具是设计师的必备能力&#xff0c;这次我们介绍一些照明工具。 1、VRaySun VRaySun是VRay渲染器中的一个功能&#xff0c;用于模拟太阳光源。它是一种方便易用的光源类型&#xff0c;能够产生逼真的日光效果…

解密Spring Boot:深入理解条件装配与条件注解

文章目录 一、条件装配概述1.1 条件装配的基本原理1.2 条件装配的作用 二、常用注解2.1 ConditionalOnClass2.2 ConditionalOnBean2.3 ConditionalOnProperty2.4 ConditionalOnExpression2.5 ConditionalOnMissingBean 三、条件装配的实现原理四、实际案例 一、条件装配概述 1…

Wireshark TS | 应用传输丢包问题

问题背景 仍然是来自于朋友分享的一个案例&#xff0c;实际案例不难&#xff0c;原因也就是互联网线路丢包产生的重传问题。但从一开始只看到数据包截图的判断结果&#xff0c;和最后拿到实际数据包的分析结果&#xff0c;却不是一个结论&#xff0c;方向有点跑偏&#xff0c;…

MySQL: 索引与事务

文章目录 1. 索引 (Index)1.1 概念1.2 作用1.3 使用场景1.4 索引的使用1.5 索引的使用案例 (不要轻易尝试)1.6 索引背后的数据结构1.7 重点总结 2.事务2.1 为什么要使用事务2.2 事务的概念2.3 事务的使用2.4 对事务的理解2.5 事务的基本特性 1. 索引 (Index) 1.1 概念 索引是…

深入STL之 栈与队列:数据结构探索之旅

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;模拟实现list与迭代器 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀stack和queue &#x1f4…

探索软件工程师在新能源汽车研发中的角色与贡献

随着全球对可持续发展的关注不断增加&#xff0c;新能源汽车的研发与应用成为了汽车行业的一个重要方向。作为软件工程师&#xff0c;参与新能源汽车研发不仅能够推动科技创新&#xff0c;还能为环保事业贡献力量。本文将深入探讨软件工程师在新能源汽车研发中的具体贡献、所需…

C#操作MySQL从入门到精通(20)——更新数据

前言: 谈到数据库,大家最容易脱口而出的就是增删改查,本文所说的更新数据就是增删改查的改,改变数据的意思。 本文测试使用的数据库如下: 1、更新一列 所谓更新一列的意思就是只更改一列数据,并且通常要使用where条件,因为不加这个条件的话会导致将所有行的数据进行…

数据可视化Python实现超详解【数据分析】

各位大佬好 &#xff0c;这里是阿川的博客&#xff0c;祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 Python 初阶 Python–语言基础与由来介绍 Python–…

后端服务器启动访问

VisualStudioCode(VSCode) 服务器启动 浏览器中测试访问 http://localhost:3000

算法笔记1-高精度模板(加减乘除)个人模板

目录 加法 减法 乘法 ​编辑 除法 加法 #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue>using namespace std;typedef pair<int,int> PII;const int N 1e5 10;int n; int a[N],…

ROS学习记录:C++节点发布自定义地图

前言 ROS栅格地图格式 在了解了ROS地图消息包的数据结构后(链接在上)&#xff0c;本文将编写一个节点&#xff0c;发布地图消息包&#xff0c;看看在RViz中显示是什么效果。 一、准备 1、为了简单起见&#xff0c;发布一个两行四列的地图 2、为了便于观测&#xff0c;只对地…

SmartEDA VS Multisim/Proteus:电子设计江湖,谁主沉浮?

在电子设计的江湖里&#xff0c;SmartEDA、Multisim和Proteus无疑是几大门派&#xff0c;各自拥有独特的武功秘籍和门派特色。今天&#xff0c;我们就来一场巅峰对决&#xff0c;看看这些电子设计软件究竟谁能笑傲江湖&#xff0c;成为电子设计界的霸主&#xff01; 一、门派起…

Seq2seq、编码器解码器神经网络

目录 一、Seq2seq 简介二、编码器三、解码器四、编码器-解码器的训练 遇到看不明白的地方&#xff0c;欢迎在评论中留言呐&#xff0c;一起讨论&#xff0c;一起进步&#xff01; 需掌握的前提知识&#xff1a; LSTM、词嵌入 本文参考&#xff1a;【官方双语】编码、解码神经网…