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

使用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函数介绍&#xff1a; select 函数是一个用于在一组文件描述符上进行异步I/O多路复用的系统调用。它可以同时监视多个文件描述符&#xff0c;等待其中任何一个文件描述符准备就绪&#xff0c;然后进行相应的操作。 以下是select函数的原型&#xff1a; #include <…...

【Python】基于OpenCV人脸追踪、手势识别控制的求实之路FPS游戏操作

【Python】基于OpenCV人脸追踪、手势识别控制的求实之路FPS游戏操作 文章目录 手势识别人脸追踪键盘控制整体代码附录&#xff1a;列表的赋值类型和py打包列表赋值BUG复现代码改进优化总结 py打包 视频&#xff1a; 基于OpenCV人脸追踪、手势识别控制的求实之路FPS游戏操作 手…...

力扣 -- 718. 最长重复子数组

解题步骤&#xff1a; 参考代码&#xff1a; class Solution { public:int findLength(vector<int>& nums1, vector<int>& nums2) {int m nums1.size();int n nums2.size();//多开一行&#xff0c;多开一列vector<vector<int>> dp(m 1, ve…...

MP、MybatisPlus、联表查询、自定义sql、Constants.WRAPPER、ew (二)

描述&#xff1a; 给定一个id列表&#xff0c;更新对应列表中动物的年龄&#xff0c;使得年龄都较少一岁。 要求&#xff1a;使用条件构造器构造条件。 mapper&#xff1a; void updateAnimalAge(Param(Constants.WRAPPER) Wrapper<Animal> wrapper, Param("age&qu…...

Ubuntu服务器安全性提升:修改SSH默认端口号

在Ubuntu服务器上&#xff0c;SSH&#xff08;Secure Shell&#xff09;是一种至关重要的远程连接工具。它提供了一种安全的方式来远程连接和管理计算机系统&#xff0c;通过加密通信来确保数据的保密性和完整性。SSH协议广泛用于计算机网络中&#xff0c;用于远程管理、文件传…...

十七,IBL-打印各个Mipmap级别的hdr环境贴图

预滤波环境贴图类似于辐照度图&#xff0c;是预先计算的环境卷积贴图&#xff0c;但这次考虑了粗糙度。因为随着粗糙度的增加&#xff0c;参与环境贴图卷积的采样向量会更分散&#xff0c;导致反射更模糊&#xff0c;所以对于卷积的每个粗糙度级别&#xff0c;我们将按顺序把模…...

7、Docker网络

docker网络模式能干嘛&#xff1f; 容器间的互联和通信以及端口映射 容器IP变动时候可以通过服务名直接网络通信而不受到影响 docker 网络模式采用的是桥接模式&#xff0c;当我们创建了一个容器后docker网络就会帮我们创建一个虚拟网卡&#xff0c;这个虚拟网卡和我们的容器网…...

MySQL学习笔记23

逻辑备份&#xff1a; 1、回顾什么是逻辑备份&#xff1f; 逻辑备份就是把数据库、数据表或者数据进行导出&#xff0c;导出到一个文本文件中。 2、逻辑备份工具&#xff1a; mysqldump&#xff1a;提供全库级、数据库级别以及表级别的数据备份。 mysqldumpbinlog&#xff…...

Java基础---第十篇

系列文章目录 文章目录 系列文章目录一、说说Java 中 IO 流二、 Java IO与 NIO的区别(补充)三、java反射的作用于原理一、说说Java 中 IO 流 Java 中 IO 流分为几种? 按照流的流向分,可以分为输入流和输出流; 按照操作单元划分,可以划分为字节流和字符流; 按照流的角色…...

NLP 03(LSTM)

一、LSTM LSTM (Long Short-Term Memory) 也称长短时记忆结构,它是传统RNN的变体,与经典RNN相比&#xff1a; 能够有效捕捉长序列之间的语义关联缓解梯度消失或爆炸现象 LSTM的结构更复杂,它的核心结构可以分为四个部分去解析: 遗忘门、输入门、细胞状态、输出门 LSTM内部结构…...

Python集成开发环境(IDE):WingPro for Mac

WingPro for Mac是一款Python集成开发环境&#xff08;IDE&#xff09;软件&#xff0c;它提供了一系列强大的工具和功能&#xff0c;帮助Python开发人员提高开发效率和质量。 WingPro for Mac拥有直观的用户界面和强大的调试器&#xff0c;可以帮助用户快速定位问题和修复错误…...

[Machine learning][Part3] numpy 矢量矩阵操作的基础知识

很久不接触数学了&#xff0c;machine learning需要用到一些数学知识&#xff0c;这里在重温一下相关的数学基础知识 矢量 矢量是有序的数字数组。在表示法中&#xff0c;矢量用小写粗体字母表示。矢量的元素都是相同的类型。例如&#xff0c;矢量不包含字符和数字。数组中元…...

【中秋国庆不断更】HarmonyOS对通知类消息的管理与发布通知(上)

一、通知概述 通知简介 应用可以通过通知接口发送通知消息&#xff0c;终端用户可以通过通知栏查看通知内容&#xff0c;也可以点击通知来打开应用。 通知常见的使用场景&#xff1a; 显示接收到的短消息、即时消息等。显示应用的推送消息&#xff0c;如广告、版本更新等。显示…...

喜讯 | 怿星科技获评SAE“优秀核心零部件企业”,测试软件平台工具广受赞誉

2023年9月22日-23日&#xff0c;SAE 2023汽车智能与网联技术国际学术会议成功举行。此次学术会议由SAE International与南昌智能新能源汽车研究院联合主办&#xff0c;大会汇聚了来自国内外智能网联领域的顶尖专家和学者。大会同期颁布的奖项旨在向行业推选出更多新时代涌现的杰…...

基于Java的医院预约挂号系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…...

福利!这两款我自制的免费配色工具你领到了吗?

​前两天刚入职&#xff0c;还没干过啥活儿&#xff0c;就迎来了中秋3天国庆7天总共8天的假期&#xff0c;美滋滋。 在这么喜庆的日子里&#xff0c;我觉得大家应该也无心科研&#xff0c;所以不如给大家发点儿福利&#xff0c;继续乐呵乐呵。 当然&#xff0c;说是福利&…...

Docker 网桥、docker0 网桥和 --net host:平台差异、使用方式和场景介绍简介:

Docker 是一个流行的容器化平台,它提供了不同的网络配置选项。其中,Docker 网桥、docker0 网桥和 --net host 是常见的网络部署方式。本文将介绍这些网络选项的平台差异、使用方式以及适用的场景。 Docker 网桥 (Bridge Networking):Docker 网桥是 Docker 默认的网络模式。在…...

【深度学习】系统架构工具链的学习笔记

1. 数据管理 数据版本控制和数据包管理&#xff1a;Activeloop Note: Scale Nucleus&#xff1a;其GitHub&#xff08;nucleus-python-client&#xff09;的stars数量少于 Deep Lake。Quilt&#xff1a;其GitHub&#xff08;quilt&#xff09;的stars数量少于 Deep Lake。...

Linux 网络编程

套接字&#xff08;Socket&#xff09;&#xff1a; 通过网络实现跨机通信 作用&#xff1a;一种文件描述符传输层的文件描述符 整个编程中&#xff0c;需要着重注意htonl/htons、ntohl/ntohs、inet_addr等 TCP的C/S实现 循环服务器模型 TCP服务器实现过程 1.创建套接字&a…...

SpringBoot读取配置的方式

在 Spring Boot 应用中&#xff0c;我们通常需要一些配置信息来指导应用的运行。这些配置信息可以包括如下内容&#xff1a;端口号、数据库连接信息、日志配置、缓存配置、认证配置、等等。Spring Boot 提供了多种方式来读取这些配置信息。读取配置的目的是为了在程序中使用这些…...

java之微信机器人二次开发文档

WTAPI框架weixin ipad 协议 在微信个人号二次开发中的应用&#xff0c;涵盖技术架构、核心功能、开发流程及安全合规要点&#xff0c;为开发者提供系统化解决方案。 ⚡ 核心能力 好友管理&#xff1a;添加好友、删除好友、修改备注、创建标签、获取好友列表、搜索好友信息 消息…...

如何用AI生成高性能无机材料?MatterGen让材料设计革命化

如何用AI生成高性能无机材料&#xff1f;MatterGen让材料设计革命化 【免费下载链接】mattergen Official implementation of MatterGen -- a generative model for inorganic materials design across the periodic table that can be fine-tuned to steer the generation tow…...

深入剖析Golang环境搭建:从基础配置到高效开发实践

1. 项目概述&#xff1a;为什么Golang环境搭建值得深究&#xff1f;如果你刚接触Go语言&#xff0c;可能会觉得“环境搭建”不就是下载、安装、配个变量吗&#xff1f;网上教程一搜一大把&#xff0c;五分钟搞定。但作为一名在多个生产环境中部署过Go服务的老兵&#xff0c;我必…...

网安从业者必学 100 个核心知识点,自查进阶必备

100条必背网络安全知识点&#xff0c;你都掌握了吗&#xff1f; 1988年&#xff0c;一款名为“莫里斯蠕虫”的程序悄然传播&#xff0c;它最初是康奈尔大学研究员的实验项目&#xff0c;目的是测量互联网规模。可谁也没想到&#xff0c;这个程序失控后感染了数千台电脑&#x…...

主芯片LP3717BTT+LP3568C,5V3.1A过认证适配器⽅案(电路原理图)

LP3717BTT LP3568C 是一套 5V/3.1A&#xff08;15.5W&#xff09;隔离型反激电源方案&#xff0c;主打"过认证、高效率、低温度"。LP3717BTT 是原边 PWM 控制器&#xff0c;LP3568C 是次级同步整流芯片&#xff0c;两者配合实现高精度恒压输出&#xff0c;板端效率可…...

DDD 中的代码组织:按技术层分 vs 按领域模块分,哪种才是正解?

前言 在实践领域驱动设计&#xff08;DDD&#xff09;时&#xff0c;你可能见过两种截然不同的代码组织方式&#xff1a;一种是传统的按技术层划分文件夹&#xff0c;另一种是按业务模块划分文件夹。两种写法的人都声称自己在做 DDD&#xff0c;那到底哪种更合理&#xff1f;本…...

十三张扑克APP

能开发十三张扑克APP的请联系我&#xff0c;有客户渠道需要这类APP&#xff0c;要开发很多款十三张...

Adobe-GenP:创意工作者的智能许可证管理解决方案

Adobe-GenP&#xff1a;创意工作者的智能许可证管理解决方案 【免费下载链接】Adobe-GenP Adobe CC 2019/2020/2021/2022/2023 GenP Universal Patch 3.0 项目地址: https://gitcode.com/gh_mirrors/ad/Adobe-GenP 在数字创意领域&#xff0c;Adobe Creative Cloud系列软…...

从UISegmentedControl迁移到TwicketSegmentedControl:完整迁移指南

从UISegmentedControl迁移到TwicketSegmentedControl&#xff1a;完整迁移指南 【免费下载链接】TwicketSegmentedControl Custom UISegmentedControl replacement for iOS, written in Swift 项目地址: https://gitcode.com/gh_mirrors/tw/TwicketSegmentedControl 想要…...

AI Agent Harness Engineering 记忆检索增强:RAG 技术在智能体中的创新应用

AI Agent Harness Engineering 记忆检索增强:RAG 技术在智能体中的创新应用 本文作者:拥有15年经验的资深软件架构师、技术博主,专注于大模型、Agent架构、云原生领域的实践与布道 本文约10200字,预计阅读时间25分钟,适合有大模型基础、想要深入了解Agent开发的中高级开发…...