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

102-Linux_I/O复用方法之poll

文章目录

  • 1.poll系统调用的作用
  • 2.poll的原型
  • 3.poll支持的事件类型
  • 4.poll实现TCP服务器
    • (1)服务器端代码:
    • (2)客户端代码:
    • (3)运行结果截图:

1.poll系统调用的作用

poll 系统调用和 select 类似,也是在指定时间内轮询一定数量的文件描述符,以测试其中是否有就绪者。

2.poll的原型

#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);

poll 系统调用成功返回就绪文件描述符的总数,超时返回 0,失败返回-1
nfds 参数指定被监听事件集合 fds 的大小。
timeout 参数指定 poll 的超时值,单位是毫秒,timeout 为-1 时,poll 调用将永久阻塞,直到某个事件发生,timeout 为 0 时,poll 调用将立即返回。

fds 参数是一个 struct pollfd 结构类型的数组,它指定所有用户感兴趣的文件描述符上发生的可读、可写和异常等事件。pollfd 结构体定义如下:
struct pollfd
{
int fd; // 文件描述符
short events; // 注册的关注事件类型
short revents; // 实际发生的事件类型,由内核填充
};
其中,fd 成员指定文件描述符,events 成员告诉 poll 监听 fd 上的哪些事件类型。
它是一系列事件的按位或,revents 成员则有内核修改,通知应用程序 fd 上实际发生了哪些事件。poll 支持的事件类型如下

3.poll支持的事件类型

在这里插入图片描述

4.poll实现TCP服务器

(1)服务器端代码:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>
#include<string.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/select.h>
#include<sys/socket.h>
#include<poll.h>#define MAXFD 10
int socket_init();
int accept_client(int sockfd);
void fds_init(struct pollfd fds[]);
void fds_add(int fd,struct pollfd fds[]);
void fds_del(int fd,struct pollfd fds[]);
void recv_data(int c,struct pollfd fds[]);
int main()
{int sockfd=socket_init();if(sockfd==-1){exit(0);}struct pollfd fds[MAXFD];fds_init(fds);fds_add(sockfd,fds);//sockfd->fdwhile(1){int  n=poll(fds,MAXFD,5000);if(n==-1){printf("poll error\n");}if(n==0){printf("time out\n");}else{for(int i=0;i<MAXFD;i++){if(fds[i].fd==-1){continue;}if(fds[i].revents & POLLIN){if(fds[i].fd == sockfd){int c=accept_client(sockfd);if(c!=-1){fds_add(c,fds);}}else{recv_data(fds[i].fd,fds);}}}}}}int socket_init()
{int sockfd=socket(AF_INET,SOCK_STREAM,0);if(sockfd==-1){return -1;}struct sockaddr_in saddr;memset(&saddr,0,sizeof(saddr));saddr.sin_family=AF_INET;saddr.sin_port=htons(5678);saddr.sin_addr.s_addr=inet_addr("127.0.0.1");int res=bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));if(res==-1){printf("bind error\n");return -1;}res=listen(sockfd,5);if(res==-1){return -1;}return sockfd;
}
int accept_client(int sockfd)
{struct sockaddr_in caddr;int len=sizeof(caddr);int c=accept(sockfd,(struct sockaddr*)&caddr,&len);return c;
}void fds_init(struct pollfd fds[])
{for(int i=0;i<MAXFD;i++){fds[i].fd=-1;fds[i].events=0;fds[i].revents=0;}
}void fds_add(int fd,struct pollfd fds[])
{for(int i=0;i<MAXFD;i++){if(fds[i].fd==-1){fds[i].fd=fd;fds[i].events=POLLIN;fds[i].revents=0;break;}}
}void fds_del(int fd,struct pollfd fds[])
{for(int i=0;i<MAXFD;i++){if(fds[i].fd==fd){fds[i].fd=-1;fds[i].events=0;fds[i].revents=0;break;}}
}void recv_data(int c,struct pollfd fds[])
{char buff[128];int n=recv(c,buff,127,0);if(n<=0){close(c);fds_del(c,fds);printf("client close\n");return ;}printf("recv:%s\n",buff);send(c,"ok",2,0);
}

(2)客户端代码:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>int socket_init();int main()
{int sockfd=socket_init();if(sockfd==-1){exit(0);}while(1){printf("input:");char buff[128]={0}; fgets(buff,127,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("read:%s\n",buff);}close(sockfd);exit(0);}int socket_init()
{int sockfd=socket(AF_INET,SOCK_STREAM,0);//tcp流式服务if(sockfd==-1){printf("socket errror\n");return -1;}struct sockaddr_in saddr;memset(&saddr,0,sizeof(saddr));saddr.sin_family=AF_INET;saddr.sin_port=htons(5678);saddr.sin_addr.s_addr=inet_addr("127.0.0.1");int res=connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));if(res==-1){printf("connect error\n");return -1;}return sockfd;
}

(3)运行结果截图:

在这里插入图片描述

相关文章:

102-Linux_I/O复用方法之poll

文章目录 1.poll系统调用的作用2.poll的原型3.poll支持的事件类型4.poll实现TCP服务器(1)服务器端代码:(2)客户端代码:(3)运行结果截图: 1.poll系统调用的作用 poll 系统调用和 select 类似&#xff0c;也是在指定时间内轮询一定数量的文件描述符&#xff0c;以测试其中是否有…...

【VAR模型 | 时间序列】帮助文档:VAR模型的引入和Python实践(含源代码)

向量自回归 (VAR) 是一种随机过程模型&#xff0c;用于捕获多个时间序列之间的线性相互依赖性。 VAR 模型通过允许多个进化变量来概括单变量自回归模型&#xff08;AR 模型&#xff09;。 VAR 中的所有变量都以相同的方式进入模型&#xff1a;每个变量都有一个方程式&#xff…...

Spark任务提交流程

1. yarn-client Driver在任务提交的本地机器上运行&#xff0c;Driver启动后会和ResourceManager通讯&#xff0c;申请启动ApplicationMaster; 随后ResourceManager分配Container&#xff0c;在合适的NodeManager上启动ApplicationMaster&#xff0c;此时的ApplicationMaster的…...

python相对路径与绝对路径

9.1 Python 绝对路径与相对路径 - 知乎 (zhihu.com) 目录 1. 绝对路径 1.1 概念 1.2 用绝对路径打开文件 1.2 相对路径 1.3 python路径表示的斜杠问题 1. 绝对路径 1.1 概念 绝对路径 指完整的描述文件位置的路径。绝对路径就是文件或文件夹在硬盘上的完整路径。 在 Win…...

SPSS如何进行基本统计分析之案例实训?

文章目录 0.引言1.描述性分析2.频数分析3.探索分析4.列联表分析5.比率分析 0.引言 因科研等多场景需要进行数据统计分析&#xff0c;笔者对SPSS进行了学习&#xff0c;本文通过《SPSS统计分析从入门到精通》及其配套素材结合网上相关资料进行学习笔记总结&#xff0c;本文对基本…...

Python项目实战篇——常用验证码标注和识别(需求分析和实现思路)

前言&#xff1a;验证码识别和标注是现在网络安全中的一个重要任务&#xff0c;尤其是在一些电商平台和在线支付等场景中&#xff0c;验证码的安全性至关重要。本文将介绍如何使用Python实现常用的验证码标注和识别&#xff0c;以便为自己的项目提供参考。 一、需求分析 1、验证…...

MySQL基础(六)多表查询

多表查询&#xff0c;也称为关联查询&#xff0c;指两个或更多个表一起完成查询操作。 前提条件&#xff1a;这些一起查询的表之间是有关系的&#xff08;一对一、一对多&#xff09;&#xff0c;它们之间一定是有关联字段&#xff0c;这个关联字段可能建立了外键&#xff0c;…...

零死角玩转stm32中级篇3-SPI总线

本篇博文目录: 一.基础知识1.什么是SPI2.SPI和IIC有什么不同3.SPI的优缺点4.SPI是怎么实现通信的5.SPI 数据传输的步骤6.SPI菊花链7.通过SPI实现数据的读和写 二.STM32F103C8T6芯片SPI协议案例代码 一.基础知识 1.什么是SPI SPI&#xff08;Serial Peripheral Interface&#…...

顺序表功能实现(入手版详解)

&#x1f349;博客主页&#xff1a;阿博历练记 &#x1f4d6;文章专栏&#xff1a;数据结构与算法 &#x1f69a;代码仓库&#xff1a;阿博编程日记 &#x1f339;欢迎关注&#xff1a;欢迎友友们点赞收藏关注哦 文章目录 &#x1f353;前言✨顺序表&#x1f50d;1.顺序表的整体…...

Java 中的线程是什么,如何创建和管理线程-下(十三)

书接上文 CompletableFuture CompletableFuture 是 Java 8 中新增的类&#xff0c;提供了更为强大的异步编程支持。它可以将多个异步任务组合成一个整体&#xff0c;并且可以处理异常情况。 例如&#xff0c;可以使用 CompletableFuture 来实现异步任务的串行执行&#xff1…...

为什么我的Windows 10 便签不支持更改字体?

Windows便签是一款常用的记录工具&#xff0c;可以帮助我们快速记录一些重要的信息。在使用Windows便签时&#xff0c;如果你想要更好地呈现你的信息&#xff0c;可以通过设置字体来达到这个效果。本文将介绍Windows便签字体设置的相关知识&#xff0c;希望对你有所帮助。 1、打…...

野火STM32电机系列(六)Cubemx配置ADC规则和注入通道

前文已经配置了GPIO、编码器 本节讲解CubeMXADC规则和注入通道 本文adc注入通道采用定时器触发&#xff0c;因此在上文定时器配置的基础上进行 常规信号&#xff08;温度等&#xff09;使用带DMA的常规通道连续采样 注入采样由定时器触发&#xff0c;采集电机三相电流&…...

预制菜,巨头们的新赛场

俗话说“民以食为天”&#xff0c;饮食对于大众的重要性自然是无需赘述。然而&#xff0c;随着生活节奏的加快&#xff0c;越来越多年轻人没有时间和精力去烹制菜肴&#xff0c;这也是外卖行业持续火热的重要原因之一。尽管如此&#xff0c;随着消费者健康意识的持续提升&#…...

英语语法第一章之英语语法综述

英语的任何句型基本都可以翻译成 什么怎么样 &#xff0c;在这里什么就是我们常说的主语&#xff0c;而怎么样就是我们常说的谓语; 可能有些小伙伴会反问&#xff0c;不是主谓宾吗&#xff1f;别急等我慢慢讲解 在这里谓语也有很有多的不同的动作 可以独立完成的动作 句型&am…...

ChatGPT被淘汰了?Auto-GPT到底有多强

大家好&#xff0c;我是可夫小子&#xff0c;关注AIGC、读书和自媒体。解锁更多ChatGPT、AI绘画玩法。 说Auto-GPT淘汰了ChatGPT了&#xff0c;显然是营销文案里面的标题党。毕竟它还是基于ChatGPT的API&#xff0c;某种意义只是基于ChatGPT能力的应用。但最近&#xff0c;Auto…...

unity NGUI使用方法

基本用法 很多基本模块比如按钮、slider等都能从Prefab中直接拖拽到场景中实现&#xff0c;但都需要有一个Collider&#xff08;Prefab已经自带&#xff09; 因为不仅是UI&#xff0c;所有带有Collider的游戏物体都能接收到OnClick&#xff0c; OnPress这样的事件——前提是需…...

软件测试技术(五)软件测试流程

软件测试流程 软件测试流程如下&#xff1a; 测试计划测试设计测试执行 单元测试集成测试确认测试系统测试验收测试回归测试验证活动 测试计划 测试计划由测试负责人来编写&#xff0c;用于确定各个测试阶段的目标和策略。这个过程将输出测试计划&#xff0c;明确要完成的测…...

Redis缓存穿透和雪崩

Redis缓存穿透和雪崩 Redis缓存的使用&#xff0c;极大的提升了应用程序的性能和效率&#xff0c;特别是数据查询方面。但同时&#xff0c;它也带来了一些问题。其中&#xff0c;最要害的问题&#xff0c;就是数据的一致性问题&#xff0c;从严格意义上讲&#xff0c;这个问题…...

【C++】set和map的使用

对于STL容器来说&#xff0c;有很多相似的功能&#xff0c;所以这里主要将与之前不同的功能说清楚 文章目录 1.对于set与map的简单理解2. setinsert迭代器遍历countmultisetinsertfindcount 3. mapinsert与迭代器的使用统计水果次数 operator []operator[]的实现理解对整体的拆…...

大学生学java编程的就业前景怎么样?我来聊聊自己的见解

今天兴哥想跟大家分享一个话题&#xff0c;就是学java到底好不好找工作。因为我发现很多粉丝朋友&#xff0c;之前可能并不是从事IT行业的&#xff0c;然后想转行来做这一行&#xff0c;或者是有些大四即将面临毕业的老哥&#xff0c;可能大学没有好好学习吧&#xff0c;然后专…...

腾讯位置服务开发者征文大赛:“独行侠”智能路线官

一个关于城市夜跑者、算法盲区与AI情感化路线推荐的真实技术实践 关键词&#xff1a;Go、地图SDK抽象、LLM Agent、Prompt工程、情感化推荐 目录 背景需求&#xff1a;都市独行侠的运动品质困境痛点诊断&#xff1a;为什么传统地图工具"听不懂人话"Module-SDK&#…...

BLE技术解析:物联网低功耗无线通信核心

1. BLE技术概述&#xff1a;物联网的无线连接基石蓝牙低功耗技术&#xff08;Bluetooth Low Energy&#xff0c;简称BLE&#xff09;自2010年作为蓝牙4.0核心规范的一部分推出以来&#xff0c;已成为物联网设备无线通信的事实标准。与经典蓝牙技术相比&#xff0c;BLE在保持相似…...

Java开发者收藏 | 你的经验不是负担,而是转型AI应用开发的加速器!

本文为Java开发者提供了清晰的AI应用开发转型路径。强调Java后端经验在AI领域是宝贵财富而非负担&#xff0c;并介绍了拥抱AI的优势。文章提出了分阶段学习路线&#xff0c;涵盖基础概念、框架选型&#xff08;Spring AI、LangChain4j、Spring AI Alibaba&#xff09;、可视化工…...

脉冲神经网络SAST训练方法:解决代理-硬件转换差距

1. 脉冲神经网络与传感器计算的挑战脉冲神经网络&#xff08;SNNs&#xff09;作为第三代神经网络模型&#xff0c;其核心特征是采用离散的脉冲信号进行信息传递和处理。这种事件驱动的计算方式与传统的连续激活神经网络&#xff08;ANNs&#xff09;有着本质区别。在传感器端计…...

[已解决]Vscode插件Keil Assistant连接Keil后出现的头文件路径无法寻找问题

问题详情 按照网络上的教程按照并且配置好vscode的Keil Assistant插件后&#xff0c;成功打开了Keil工程并且编译成功。但是头文件无法跳转&#xff0c;以及出现红色波浪线报错。 解决方法 在.vscode\c_cpp_properties.json中添加以下两行路径&#xff1a; "includePath&q…...

深度相机三剑客:TOF、双目与结构光的场景化选型指南

1. 深度相机技术入门&#xff1a;从原理到应用 第一次接触深度相机时&#xff0c;我被各种技术名词搞得晕头转向。TOF、双目、结构光听起来都很高大上&#xff0c;但到底有什么区别&#xff1f;经过多年项目实战&#xff0c;我发现这三种技术就像不同的"眼睛"&#…...

Codex客户端Mac低版本安装解决方法

Codex客户端Mac低版本安装解决方法 关键词&#xff1a;Codex客户端安装、Mac系统版本过低、无法安装Codex、Mac兼容性问题解决、Codex客户端下载、Mac软件安装失败 在实际开发环境里&#xff0c;很多工具对 macOS 版本都有最低要求限制。最近在本地尝试安装 Codex 客户端时&am…...

服务器运维与DevOps融合:迈向智能化运维的新纪元

在数字化浪潮席卷全球的今天&#xff0c;企业对IT基础设施的依赖程度日益加深&#xff0c;服务器运维作为支撑业务连续性和系统稳定性的核心环节&#xff0c;正面临前所未有的挑战与机遇。传统运维模式依赖人工干预、响应滞后、效率低下&#xff0c;已难以满足现代业务快速迭代…...

新手也能看懂的SQL注入绕过实战:以BUUCTF的BabySQL靶场为例,手把手教你双写绕过

从零破解BabySQL&#xff1a;双写绕过的艺术与科学 当你第一次接触CTF比赛中的SQL注入题目时&#xff0c;那种既兴奋又困惑的感觉一定记忆犹新。面对BabySQL这样的靶场&#xff0c;新手常会遇到一个典型困境&#xff1a;明明知道应该用union select来获取数据&#xff0c;却发现…...

从单机到集群的基石:手把手配置ZooKeeper 3.5.8单机模式,为分布式应用铺路

从单机到集群的基石&#xff1a;手把手配置ZooKeeper 3.5.8单机模式&#xff0c;为分布式应用铺路 在分布式系统的世界里&#xff0c;协调服务就像交响乐团的指挥&#xff0c;确保每个乐器&#xff08;节点&#xff09;在正确的时间演奏正确的音符。ZooKeeper正是这样一个"…...