使用select实现服务器并发
select函数介绍:
select 函数是一个用于在一组文件描述符上进行异步I/O多路复用的系统调用。它可以同时监视多个文件描述符,等待其中任何一个文件描述符准备就绪,然后进行相应的操作。
以下是select函数的原型:
#include <sys/select.h>int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);参数:
nfds:待监视的最大文件描述符加1。
 readfds:指向一个可读文件描述符集合的指针,用于指定要监视读事件的文件描述符。
 writefds:指向一个可写文件描述符集合的指针,用于指定要监视写事件的文件描述符。
 exceptfds:指向一个异常文件描述符集合的指针,用于指定要监视异常事件的文件描述符。
 timeout:指向一个表示超时时间的结构体指针,用于设置select的超时时间。如果为NULL,select将一直阻塞,直到有事件发生。
返回值:
如果超时时间内有文件描述符就绪或有错误发生,select函数返回就绪文件描述符的总数。
 如果超时时间到达而没有文件描述符就绪,select函数返回0。
 如果出现错误,select函数返回-1,并设置errno来指示具体的错误类型。
 select函数主要用于实现多路复用的I/O操作,它允许同时监视多个文件描述符,以避免使用阻塞式I/O时每个文件描述符都需要单独的线程。通过select函数,可以有效地管理并发连接、处理I/O事件和提高系统性能。
  
服务器代码:
#include <myhead.h>#define PORT 9999               //端口号
#define IP "192.168.125.39"     //本机IPint main(int argc, const char *argv[])
{//创建流式套接字 socketint sfd=socket(AF_INET,SOCK_STREAM,0);if(sfd<0){ERR_MSG("socket create");return -1;}//允许端口快速的被复用int reuse = 1;                                                            if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0){ERR_MSG("setsockopt");return -1;}printf("允许端口快速的被复用成功\n");//填充地址信息结构体给bind函数绑定//真实的地址信息结构体根据地址族指定 AF_INET:man 7 ipstruct sockaddr_in sin;sin.sin_family = AF_INET; //必须填AF_INETsin.sin_port = htons(PORT); //端口号的网络字节序sin.sin_addr.s_addr = inet_addr(IP);//本机ip//绑定服务器的地址信息 必须绑定bindif(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0){ERR_MSG("bind");return -1;}//将套接字设置为被动监听状态listenif(listen(sfd,128)<0){ERR_MSG("listen");return -1;}//创建一个读集合fd_set readfds,tempfds;//fd_set 本质上是一个结构体,结构体中有一个整形数组//清空集合,存在随机值,可能会随机到有用的但是不需要监测的文件描述符//清空集合FD_ZERO(&readfds);//将要监测的文件描述符添加到集合中FD_SET(0,&readfds);FD_SET(sfd,&readfds);int maxfd = sfd;      //储存最大文件描述符char buff[128] = "";int s_res = -1;char buf[128] = "";ssize_t res = -1;struct sockaddr_in saveCin[1024];   //备份连接成功的客户端的地址信息,用下标对应文件描述符while(1){tempfds = readfds;//执行IO多路复用函数s_res = select(maxfd+1,&tempfds,NULL,NULL,NULL);if(s_res <0){ERR_MSG("select");return -1;}else if(s_res == 0){printf("time out,, \n");break;}//此时集合中会只剩下产生事件的文件描述符//只需要判断集合中剩下哪个文件描述符,走对应处理函数for(int i=0;i<=maxfd;i++ ){if(FD_ISSET(i,&tempfds)==0)continue;//能运行到这里,说明i代表的文件描述符在集合中if(0 == i){int sendfd = -1;printf("触发键盘事件\n");bzero(buff,sizeof(buff));int res=scanf("%d %s",&sendfd,buff);while(getchar()!=10);if(2!=res){printf("输入格式错误\n");return -1;}if(2>=sendfd || FD_ISSET(sendfd,&readfds)==0){printf("输入有误\n");return -1;}if(send(sendfd,buff,sizeof(buff),0)<0){ERR_MSG("send");return -1;}}else if(sfd == i){printf("触发客户端连接事件\n");//连接到客户端//获取一个已经完成的客户端信息,生成一个新的文件描述符int newfd = -1;struct sockaddr_in cin;//存储客户端的地址信息socklen_t addrlen = sizeof(cin);//真实的结构体信息地址大小newfd = accept(sfd,(struct sockaddr*)&cin,&addrlen);if(newfd<0){ERR_MSG("newfd");return -1;}printf("[%s %d]:%d\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd);saveCin[newfd] = cin;//将newfd添加到集合中FD_SET(newfd,&readfds);//更新最大文件描述符maxfd = maxfd>newfd?maxfd:newfd;}else{printf("触发客户端交互事件\n");bzero(buf,sizeof(buf));res = recv(i,buf,sizeof(buf),0);if(res<0){ERR_MSG("recv");return -1;}if(0 == res){printf("[%s %d]客户端下线:%d",inet_ntoa(saveCin[i].sin_addr),ntohs(saveCin[i].sin_port),i);//关闭文件描述符	close(i);//剔除文件描述符FD_CLR(i, &readfds);while(!FD_ISSET(maxfd, &readfds)&& (maxfd--) > 0);continue;}printf("[%s %d]%d:%s\n",inet_ntoa(saveCin[i].sin_addr),ntohs(saveCin[i].sin_port),i,buf);}}}//关闭if(close(sfd)<0){ERR_MSG("close");return -1;}return 0;
}
相关文章:
使用select实现服务器并发
select函数介绍: select 函数是一个用于在一组文件描述符上进行异步I/O多路复用的系统调用。它可以同时监视多个文件描述符,等待其中任何一个文件描述符准备就绪,然后进行相应的操作。 以下是select函数的原型: #include <…...
 
【Python】基于OpenCV人脸追踪、手势识别控制的求实之路FPS游戏操作
【Python】基于OpenCV人脸追踪、手势识别控制的求实之路FPS游戏操作 文章目录 手势识别人脸追踪键盘控制整体代码附录:列表的赋值类型和py打包列表赋值BUG复现代码改进优化总结 py打包 视频: 基于OpenCV人脸追踪、手势识别控制的求实之路FPS游戏操作 手…...
 
力扣 -- 718. 最长重复子数组
解题步骤: 参考代码: class Solution { public:int findLength(vector<int>& nums1, vector<int>& nums2) {int m nums1.size();int n nums2.size();//多开一行,多开一列vector<vector<int>> dp(m 1, ve…...
MP、MybatisPlus、联表查询、自定义sql、Constants.WRAPPER、ew (二)
描述: 给定一个id列表,更新对应列表中动物的年龄,使得年龄都较少一岁。 要求:使用条件构造器构造条件。 mapper: void updateAnimalAge(Param(Constants.WRAPPER) Wrapper<Animal> wrapper, Param("age&qu…...
 
Ubuntu服务器安全性提升:修改SSH默认端口号
在Ubuntu服务器上,SSH(Secure Shell)是一种至关重要的远程连接工具。它提供了一种安全的方式来远程连接和管理计算机系统,通过加密通信来确保数据的保密性和完整性。SSH协议广泛用于计算机网络中,用于远程管理、文件传…...
 
十七,IBL-打印各个Mipmap级别的hdr环境贴图
预滤波环境贴图类似于辐照度图,是预先计算的环境卷积贴图,但这次考虑了粗糙度。因为随着粗糙度的增加,参与环境贴图卷积的采样向量会更分散,导致反射更模糊,所以对于卷积的每个粗糙度级别,我们将按顺序把模…...
 
7、Docker网络
docker网络模式能干嘛? 容器间的互联和通信以及端口映射 容器IP变动时候可以通过服务名直接网络通信而不受到影响 docker 网络模式采用的是桥接模式,当我们创建了一个容器后docker网络就会帮我们创建一个虚拟网卡,这个虚拟网卡和我们的容器网…...
 
MySQL学习笔记23
逻辑备份: 1、回顾什么是逻辑备份? 逻辑备份就是把数据库、数据表或者数据进行导出,导出到一个文本文件中。 2、逻辑备份工具: mysqldump:提供全库级、数据库级别以及表级别的数据备份。 mysqldumpbinlogÿ…...
 
Java基础---第十篇
系列文章目录 文章目录 系列文章目录一、说说Java 中 IO 流二、 Java IO与 NIO的区别(补充)三、java反射的作用于原理一、说说Java 中 IO 流 Java 中 IO 流分为几种? 按照流的流向分,可以分为输入流和输出流; 按照操作单元划分,可以划分为字节流和字符流; 按照流的角色…...
 
NLP 03(LSTM)
一、LSTM LSTM (Long Short-Term Memory) 也称长短时记忆结构,它是传统RNN的变体,与经典RNN相比: 能够有效捕捉长序列之间的语义关联缓解梯度消失或爆炸现象 LSTM的结构更复杂,它的核心结构可以分为四个部分去解析: 遗忘门、输入门、细胞状态、输出门 LSTM内部结构…...
 
Python集成开发环境(IDE):WingPro for Mac
WingPro for Mac是一款Python集成开发环境(IDE)软件,它提供了一系列强大的工具和功能,帮助Python开发人员提高开发效率和质量。 WingPro for Mac拥有直观的用户界面和强大的调试器,可以帮助用户快速定位问题和修复错误…...
 
[Machine learning][Part3] numpy 矢量矩阵操作的基础知识
很久不接触数学了,machine learning需要用到一些数学知识,这里在重温一下相关的数学基础知识 矢量 矢量是有序的数字数组。在表示法中,矢量用小写粗体字母表示。矢量的元素都是相同的类型。例如,矢量不包含字符和数字。数组中元…...
 
【中秋国庆不断更】HarmonyOS对通知类消息的管理与发布通知(上)
一、通知概述 通知简介 应用可以通过通知接口发送通知消息,终端用户可以通过通知栏查看通知内容,也可以点击通知来打开应用。 通知常见的使用场景: 显示接收到的短消息、即时消息等。显示应用的推送消息,如广告、版本更新等。显示…...
 
喜讯 | 怿星科技获评SAE“优秀核心零部件企业”,测试软件平台工具广受赞誉
2023年9月22日-23日,SAE 2023汽车智能与网联技术国际学术会议成功举行。此次学术会议由SAE International与南昌智能新能源汽车研究院联合主办,大会汇聚了来自国内外智能网联领域的顶尖专家和学者。大会同期颁布的奖项旨在向行业推选出更多新时代涌现的杰…...
 
基于Java的医院预约挂号系统设计与实现(源码+lw+部署文档+讲解等)
文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding)有保障的售后福利 代码参考源码获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…...
 
福利!这两款我自制的免费配色工具你领到了吗?
前两天刚入职,还没干过啥活儿,就迎来了中秋3天国庆7天总共8天的假期,美滋滋。 在这么喜庆的日子里,我觉得大家应该也无心科研,所以不如给大家发点儿福利,继续乐呵乐呵。 当然,说是福利&…...
Docker 网桥、docker0 网桥和 --net host:平台差异、使用方式和场景介绍简介:
Docker 是一个流行的容器化平台,它提供了不同的网络配置选项。其中,Docker 网桥、docker0 网桥和 --net host 是常见的网络部署方式。本文将介绍这些网络选项的平台差异、使用方式以及适用的场景。 Docker 网桥 (Bridge Networking):Docker 网桥是 Docker 默认的网络模式。在…...
【深度学习】系统架构工具链的学习笔记
1. 数据管理 数据版本控制和数据包管理:Activeloop Note: Scale Nucleus:其GitHub(nucleus-python-client)的stars数量少于 Deep Lake。Quilt:其GitHub(quilt)的stars数量少于 Deep Lake。...
 
Linux 网络编程
套接字(Socket): 通过网络实现跨机通信 作用:一种文件描述符传输层的文件描述符 整个编程中,需要着重注意htonl/htons、ntohl/ntohs、inet_addr等 TCP的C/S实现 循环服务器模型 TCP服务器实现过程 1.创建套接字&a…...
 
SpringBoot读取配置的方式
在 Spring Boot 应用中,我们通常需要一些配置信息来指导应用的运行。这些配置信息可以包括如下内容:端口号、数据库连接信息、日志配置、缓存配置、认证配置、等等。Spring Boot 提供了多种方式来读取这些配置信息。读取配置的目的是为了在程序中使用这些…...
 
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
 
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
 
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
 
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
 
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
 
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
