148 Linux 网络编程4 ,高并发服务器 --多路I/O转接服务器 - poll 这个非重点,

Poll 的实现和 select 很像。

实际上poll 的核心就是我们select的优化版本,加入了一个数组,

还将传入传出参数分离开了

#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);fds :需要监听的--文件描述符数组,注意是数组struct pollfd {int fd; /* 文件描述符 */short events; /* 监控的事件 */short revents; /* 监控事件中满足条件返回的事件 */};POLLIN			普通或带外优先数据可读,即POLLRDNORM | POLLRDBANDPOLLRDNORM		数据可读POLLRDBAND		优先级带数据可读POLLPRI 		高优先级可读数据POLLOUT		普通或带外数据可写POLLWRNORM		数据可写POLLWRBAND		优先级带数据可写POLLERR 		发生错误POLLHUP 		发生挂起POLLNVAL 		描述字不是一个打开的文件nfds 			监控数组中有多少文件描述符需要被监控timeout 		毫秒级等待-1:阻塞等,#define INFTIM -1 			Linux中没有定义此宏0:立即返回,不阻塞进程>0:等待指定毫秒数,如当前系统时间精度不够毫秒,向上取值

如果不再监控某个文件描述符时,可以把pollfd中,fd设置为-1,poll不再监控此pollfd,下次返回时,把revents设置为0。
相较于select而言,poll的优势:
    1. 传入、传出事件分离。无需每次调用时,重新设定监听事件。
    2. 文件描述符上限,可突破1024限制。能监控的最大上限数可使用配置文件调整。

缺点:

无法跨平台,只能在linux 上使用,

无法直接定位满足监听事件的文件描述符,和select 一样 也需要轮询

/* server.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <poll.h>
#include <errno.h>
#include "wrap.h"#define MAXLINE 80
#define SERV_PORT 6666
#define OPEN_MAX 1024int main(int argc, char *argv[])
{int i, j, maxi, listenfd, connfd, sockfd;int nready;ssize_t n;char buf[MAXLINE], str[INET_ADDRSTRLEN];socklen_t clilen;struct pollfd client[OPEN_MAX];struct sockaddr_in cliaddr, servaddr;listenfd = Socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(SERV_PORT);Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));Listen(listenfd, 20);client[0].fd = listenfd;client[0].events = POLLIN; 					/* listenfd监听普通读事件 */for (i = 1; i < OPEN_MAX; i++)client[i].fd = -1; 							/* 用-1初始化client[]里剩下元素 */maxi = 0; 										/* client[]数组有效元素中最大元素下标 */for ( ; ; ) {nready = poll(client, maxi+1, -1); 			/* 阻塞 */if (client[0].revents & POLLIN) { 		/* 有客户端链接请求 */clilen = sizeof(cliaddr);connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);printf("received from %s at PORT %d\n",inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),ntohs(cliaddr.sin_port));for (i = 1; i < OPEN_MAX; i++) {if (client[i].fd < 0) {client[i].fd = connfd; 	/* 找到client[]中空闲的位置,存放accept返回的connfd */break;}}if (i == OPEN_MAX)perr_exit("too many clients");client[i].events = POLLIN; 		/* 设置刚刚返回的connfd,监控读事件 */if (i > maxi)maxi = i; 						/* 更新client[]中最大元素下标 */if (--nready <= 0)continue; 						/* 没有更多就绪事件时,继续回到poll阻塞 */}for (i = 1; i <= maxi; i++) { 			/* 检测client[] */if ((sockfd = client[i].fd) < 0)continue;if (client[i].revents & POLLIN) {if ((n = Read(sockfd, buf, MAXLINE)) < 0) {if (errno == ECONNRESET) { /* 当收到 RST标志时 *//* connection reset by client */printf("client[%d] aborted connection\n", i);Close(sockfd);client[i].fd = -1;} else {perr_exit("read error");}} else if (n == 0) {/* connection closed by client */printf("client[%d] closed connection\n", i);Close(sockfd);client[i].fd = -1;} else {for (j = 0; j < n; j++)buf[j] = toupper(buf[j]);Writen(sockfd, buf, n);}if (--nready <= 0)break; 				/* no more readable descriptors */}}}return 0;
}

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

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

相关文章

数据挖掘|数据集成|基于Python的数据集成关键问题处理

数据挖掘|数据集成|基于Python的数据集成关键问题处理 1. 实体识别2. 数据冗余与相关性分析3. 去除重复记录4. 数据值冲突的检测与处理5. 基于Python的数据集成5.1 merge()方法5.2 Concat()方法 数据集成是把来自多个数据库或文件等不同数据源的数据整合成一致的数据存储。其中…

基于docker创建深度学习开发环境

基于docker创建深度学习开发环境 记录几个链接 第一步&#xff1a;配置docker环境&#xff0c;此处大把教程&#xff0c;不再赘述第二步&#xff1a;拉取nvidia做好的cuda和cudnn镜像&#xff1a; docker pull nvcr.io/nvidia/cuda:12.2.0-devel-ubuntu20.04如果有其他需求&a…

vue3+threejs新手从零开发卡牌游戏(二):初始化场景

在删掉初始化中一些没用的代码后&#xff0c;在views目录下新建game文件夹&#xff0c;在里面新建一个index.vue&#xff0c;这里就当成游戏的主入口。 目录结构如下&#xff1a; 下面开始尝试创建场景&#xff1a; 一、添加一个div作为threejs的画布对象&#xff0c;之后整个…

ubuntu - 编译 linphone-sdk

业务需求需要定制sdk&#xff0c;首先声明我们需要的是在Android4.4上跑的sdk&#xff0c;因此本次编译的sdk最低支持为19&#xff08;不同版本需要的环境不一致&#xff09;&#xff0c;编译过程较容易&#xff0c;难点在于环境配置 环境准备 Ubuntu 18.04.6 android-sdk_r24.…

mysql分页查询多用GitCode平台

目录 一、在GitCode平台AI搜索结果&#xff08;这个更优&#xff09; 二、在百度搜索输入“mysql Java分页查询”的输出结果&#xff1a; 三、推荐的文章 四、GitCode的使用 1&#xff09;如搜索jdk11可以直接下载jdk11的包 2&#xff09;搜索开源项目 3&#xff09;如搜…

3.21 ARM day5

串口控制LED灯亮灭 main.c #include "uart4.h"int main() {//串口初始化uart4_init();//led初始化led_init();char i;int count 0;int count2 0;int count3 0;while (1){i getchar();putchar(i);//键盘输入a&#xff0c;串口工具显示aif (i 1){count;if (coun…

步进电机驱动器的接线与使用(接线详细)

今天小编就来继续学习与使用步行电机的学习&#xff0c;如果位置对你有帮助&#xff0c;评论收藏&#xff0c;点赞一下 步进电机驱动器 步进电机驱动器是一种专用于控制步进电机的电子设备&#xff0c;用于控制步进电机的转动和位置。步进电机是一种将电信号转换为机械运动的电…

Compose UI 之 Segmented buttons 分段按钮

Segmented buttons SegmentedButton 是一种分段式按钮组件,它允许用户在一组相关的选项中选择一个或几个。 上图中:① 单选的分段式按钮。② 多选的分段式按钮。 分段式按钮的几个特点: 分段式按钮是带有状态的按钮,又有单选和多选之分。 从设计上将,不论是单选或是多选…

第二十九章 配置 Web Gateway 的默认参数 - 与 IRIS 的连接(二)

文章目录 第二十九章 配置 Web Gateway 的默认参数 - 与IRIS 的连接(二)Event Log Rotation SizeMaximum Logged Request SizeSSL/TLS Library PathPreserve Mode Exclude File Types 第二十九章 配置 Web Gateway 的默认参数 - 与IRIS 的连接(二) Event Log Rotation Size 这…

fastjson2 反序列化包含多层泛型结构的实体类

前言 由于使用到httpUtill来调用接口 工具类的返回是字符串 其中接口的实现返回值是个多层泛型结构的实体类 例如Result<Page<UserDto>> 当使用 JSON.parseObject("res",new TypeReference<Result<Page<UserDto>>>{})发现在page中存在…

【GPT概念-03】:人工智能中的注意力机制

说明 注意力机制生成分数&#xff08;通常使用输入函数&#xff09;&#xff0c;确定对每个数据部分的关注程度。这些分数用于创建输入的加权总和&#xff0c;该总和馈送到下一个网络层。这允许模型捕获数据中的上下文和关系&#xff0c;而传统的固定序列处理方法可能会遗漏这…

QT(19)-QNetworkRequest

attribute(QNetworkRequest::Attribute code, const QVariant &defaultValue QVariant()) const 获取指定的请求属性。如果该属性未设置&#xff0c;则返回默认值。 hasRawHeader(const QByteArray &headerName) const 检查是否存在指定名称的原始请求头。 header(Q…

虚拟机扩展:虚拟机快照

虚拟机快照 在学习阶段我们无法避免的可能损坏Linux操作系统。如果损坏的话&#xff0c;重新安装一个Linux操作系统就会十分麻烦。 那我们就可以通过快照将当前虚拟机的状态保存下来&#xff0c;在以后系统损坏时通过快照恢复虚拟机到保存的状态。 制作并还原快照 在VMware …

静态方法 static foo()

静态方法&#xff08;Static Method&#xff09;是编程语言中的一种特殊方法&#xff0c;其特点是不依赖于类的实例即可被调用。在C和许多其他面向对象的编程语言中&#xff0c;静态方法通过类名来直接调用&#xff0c;而无需创建类的实例。这些方法属于类本身&#xff0c;而不…

数据结构(二)队列和栈

Java提供了java.util.Stack类来表示栈数据结构。Stack类是Vector类的子类&#xff0c;它实现了一个标准的后进先出&#xff08;LIFO&#xff09;栈。同样也提供了Queue接口&#xff0c;表示一系列按照特定顺序排列的元素&#xff0c;其中最早添加的元素将最先被移除&#xff08…

SAP HCM 0008信息类型间接评估与直接评估

如果在间接评估模块输入就是间接评估&#xff08;tarif是读取下图中的数据 a代表不需要输入工资项&#xff0c;b表示需要找工资相&#xff09; 不输入就是直接评估需要客户自己输入数字 第2个情况 summe求和 &#xff08;比如在0008中输入9000与9001 那么自动求出9002工资项数…

C# WPF编程-布局

C# WPF编程-布局 布局WPF布局原则布局过程布局容器布局属性Border控件StackPanel布局WrapPanel布局DockPanel布局Grid布局UniformGrid布局Canvas布局 布局 WPF布局原则 WPF窗口只能包含单个元素。为在WPF窗口中放置多个元素并创建更贴近实用的用户界面&#xff0c;需要在窗口…

uniapp 之 一些常用方法的封装(页面跳转,页面传参等)

util.js 提示&#xff1a;permission.js是uniapp插件市场由官方DCloud_heavensoft提供的App权限判断和提示插件。 import permision from "/js_sdk/wa-permission/permission.js"/*** uni.toast 封装* param {String} msg toast 提示内容* param {Number} duration …

SpringBoot项目如何打包成war包,并部署在tomcat上运行

项目场景&#xff1a; 正常情况下&#xff0c;我们开发 SpringBoot 项目&#xff0c;由于内置了Tomcat&#xff0c;所以项目可以直接启动&#xff0c;部署到服务器的时候&#xff0c;直接打成 jar 包&#xff0c;就可以运行了。 有时我们会需要打包成 war 包&#xff0c;放入外…

Redis进阶(持久化、复制、集群、多线程、缓存)

Redis进阶 1.Redis持久化1.1 什么是Redis持久化&#xff1f;为什么需要持久化&#xff1f;1.2 Redis持久化方式——RDB(Redis DataBase)1.2.1 什么是RDB&#xff1f;1.2.2 备份文件位置1.2.3 触发RDB的方式1.2.3.1 自动触发1.2.3.2 手动触发1.2.3.3 其他触发方式 1.2.4 RDB优缺…