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

Linux IO模型:IO多路复用

● 应用程序中同时处理多路输入输出流,若采用阻塞模式,得不到预期的目的;

若采用非阻塞模式,对多个输入进行轮询,但又太浪费CPU时间;

若设置多个进程/线程,分别处理一条数据通路,将新产生进程/线程间的同步与通信问题,使程序变得更加复杂;

比较好的方法是使用I/O多路复用技术

其(select)基本思想是:

先构造一张有关描述符的表(最大1024),然后调用一个函数。

当这些文件描述符中的一个或多个已准备好进行I/O时函数才返回。

函数返回时告诉进程哪个描述符已就绪,可以进行I/O操作。

用select创建并发服务器,可以与多个客户端进行通信(监听键盘、socket、多个acceptfd)

循环服务器一个客户端可以连接多个客户但是不能同时

并发服务器一个服务器可以同时处理多个客户端的请求

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>// tcp服务器一共有两种文件描述符,一类用于连接,一类用于通信
int main(int argc, char const *argv[])
{char buf[128];int ret;if (argc != 2){printf("usage:%s <端口号>\n", argv[0]);return -1;}// 1.创建套接字(socket)// socket函数返回值:用于连接的文件描述符int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){perror("socket err");return -1;}printf("sockfd:%d\n", sockfd);// 2. 指定网络信息struct sockaddr_in saddr, caddr;saddr.sin_family = AF_INET;            // IPV4saddr.sin_port = htons(atoi(argv[1])); // 端口号// saddr.sin_addr.s_addr = inet_addr("0.0.0.0"); // 虚拟机IP地址(自动获取)saddr.sin_addr.s_addr = INADDR_ANY; // 虚拟机IP地址// INADDR_ANY是一个常量,它指代的是一个特殊的IP地址,即0.0.0.0// 在网络编程中,当一个进程需要绑定一个网络端口时,可以使用INADDR_ANY来指定该端口可以接受来自任何IP地址的连接请求int len = sizeof(caddr);// 3.绑定套接字(bind)if (bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0){perror("bind err");return -1;}printf("bind ok\n");// 4.监听套接字(listen)if (listen(sockfd, 6) < 0){perror("listen err");return -1;}printf("listen ok\n");//******************************************************************//// 1)构造一张关于文件描述符的表fd_set rfds, tempfds;int maxfd;// 2)清空表 FD_ZEROFD_ZERO(&rfds);FD_ZERO(&tempfds);// 3)将关心的文件描述符添加到表中 FD_SETFD_SET(sockfd, &rfds);FD_SET(0, &rfds);maxfd = sockfd;while (1){// 将原来的表复制给新表tempfds = rfds;struct timeval tm = {1, 0}; // 超时检测// 4)调用select函数,监听 selectret = select(maxfd + 1, &tempfds, NULL, NULL, 0);if (ret < 0){perror("select err");return -1;}else if(ret==0){printf("time out\n");}// 5)判断到底是哪一个或者是哪些文件描述符发生了事件 FD_ISSETif (FD_ISSET(0, &tempfds)){fgets(buf, sizeof(buf), stdin);printf("keybroad:%s\n", buf);}if (FD_ISSET(sockfd, &tempfds)){// 5.接受客户端连接请求(accept)// accept函数返回值:用于通信的文件描述符int acceptfd = accept(sockfd, (struct sockaddr *)&caddr, &len);if (acceptfd < 0){perror("accpet err");return -1;}printf("port:%d ip:%s\n", ntohs(caddr.sin_port), inet_ntoa(caddr.sin_addr));printf("accpetfd:%d\n", acceptfd);// 将用于通信的文件描述符加入表中FD_SET(acceptfd, &rfds);if (acceptfd > maxfd)maxfd = acceptfd;}for (int i = sockfd + 1; i <= maxfd; i++) // 循环判断哪些文件描述符发生响应{if (FD_ISSET(i, &tempfds)){// 6. 接收,发送数据(recv,send)ret = recv(i, buf, sizeof(buf), 0);if (ret < 0){perror("recv err");break;}else if (ret == 0){printf("client %d exit\n", i);close(i);         // 关闭退出的客户端文件描述符FD_CLR(i, &rfds); // 将关闭的文件描述符从表中删除while (!FD_ISSET(maxfd, &rfds))maxfd--;}else{printf("client %d: %s\n", i, buf);memset(buf, 0, sizeof(buf));}}}}//*****************************************************************//// 7.关闭套接字(close)close(sockfd);return 0;
}

使用poll实现client的收发功能

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
#include <poll.h>
int main(int argc, char const *argv[])
{char buf[128];if (argc != 3){printf("usage:%s <IP地址> <端口号>\n", argv[0]);return -1;}// 1.创建套接字(socket)int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){perror("socket err");return -1;}printf("sockfd:%d\n", sockfd);// 2.指定(服务器)网络信息struct sockaddr_in saddr;saddr.sin_family = AF_INET;                 // IPV4saddr.sin_port = htons(atoi(argv[2]));      // 端口号saddr.sin_addr.s_addr = inet_addr(argv[1]); // 虚拟机IP地址// 3.连接(connect)if (connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0){perror("connect err");return -1;}printf("connect ok\n");// 4.接收发送消息(recv send)//************************************************************//// 1)创建结构体数组struct pollfd fds[2];// 2)将关心的文件描述符添加到数组中,并赋予事件fds[0].fd = 0;          // 键盘fds[0].events = POLLIN; // 想要发生的事件fds[1].fd = sockfd;     // 套接字fds[1].events = POLLIN; // 想要发生的事件// 3)保存数组内最后一个有效元素的下标int last = 1;// 4)调用poll函数,监听while (1){int ret = poll(fds, last + 1, 0);if (ret < 0){perror("poll err");return -1;}// 5)判断结构体内文件描述符实际触发的事件if (fds[0].revents == POLLIN){// 6)根据不同文件描述符触发的不同事件做对应的逻辑处理fgets(buf, sizeof(buf), stdin);// printf("keybroad:%s\n", buf);send(sockfd, buf, sizeof(buf), 0);if (strcmp(buf, "quit\n") == 0)break;}if (fds[1].revents == POLLIN){recv(sockfd, buf, sizeof(buf), 0);printf("buf:%s\n", buf);}memset(buf, 0, sizeof(buf));}//************************************************************//// 5.关闭套接字(close)close(sockfd);return 0;
}

相关文章:

Linux IO模型:IO多路复用

● 应用程序中同时处理多路输入输出流&#xff0c;若采用阻塞模式&#xff0c;得不到预期的目的&#xff1b; ● 若采用非阻塞模式&#xff0c;对多个输入进行轮询&#xff0c;但又太浪费CPU时间&#xff1b; ● 若设置多个进程/线程&#xff0c;分别处理一条数据通路&#xff…...

[数据集][目标检测]电梯内广告牌电动车检测数据集VOC+YOLO格式2787张4类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2787 标注数量(xml文件个数)&#xff1a;2787 标注数量(txt文件个数)&#xff1a;2787 标注…...

MATLAB下载详细教程及下载链接

欢迎大家进评论区交流经验 1. 准备工作 下载MATLAB安装包&#xff1a;首先&#xff0c;从MathWorks官方网站&#xff08;http://www.mathworks.com&#xff09;下载适合您操作系统的MATLAB安装包。确保选择与您的操作系统&#xff08;如Windows、macOS或Linux&#xff09;兼容的…...

利用发电量和气象数据分析来判断光伏仿真系统的准确性

随着光伏产业的迅速发展&#xff0c;光伏仿真系统通过集成气象数据分析、发电量分析、投融资分析及损耗估算等功能&#xff0c;为光伏项目的全生命周期管理提供了科学依据。 光伏仿真系统集成了气象数据分析、发电量预测、投融资分析、损耗估算及光伏设计等功能。其中&#xf…...

Model-based RL动态规划(基于价值、基于策略,泛化迭代)

白盒环境和黑盒环境 白盒环境&#xff1a;知道环境的状态转移函数P(s’|s)或P(s’|s,a)和奖励函数R(s)或R(s,a)&#xff1a;   白盒环境下的学习相当于直接给出了有监督学习的数据分布&#xff08;就是有了目标靶子&#xff09;&#xff0c;不需要采样了&#xff0c;直接最小…...

外接串口板,通过串口打开adb模式

一、依赖库 import subprocess import serial from serial.tools import list_ports import logging import time 二、代码 import subprocessimport serial from serial.tools import list_ports import logging import timedef openAdb(com):# com []# for i in list_por…...

ssm微信小程序校园失物招领论文源码调试讲解

第二章 开发技术与环境配置 以Java语言为开发工具&#xff0c;利用了当前先进的SSM框架&#xff0c;以MyEclipse10为系统开发工具&#xff0c;MySQL为后台数据库&#xff0c;开发的一个微信小程序校园失物招领。 2.1 Java语言简介 Java是由SUN公司推出&#xff0c;该公司于20…...

iOS 15推出后利用邮件打开率的7种方法

自从苹果在2021年底推出iOS 15以来&#xff0c;邮件打开率就一直是一个让人头疼的指标。 Klaviyo市场情报主管Mindy Regnell表示&#xff1a;“对于启用了Apple邮件隐私保护&#xff08;MPP&#xff09;的用户来说&#xff0c;苹果会打开这些邮件并预先下载内容到他们的服务器…...

以太网--TCP/IP协议(一)

概述 以太网是局域网的一种&#xff0c;其他的比如还有令牌环、FDDI。和局域网对应的就是广域网&#xff0c;如Internet&#xff0c;城域网等。 从网络层次看&#xff0c;局域网协议主要偏重于低层&#xff08;业内一般把物理层、数据链路层归为低层&#xff09;。以太网协议…...

LeetCode刷题:找到第K大的元素

本题其实就是考察排序算法&#xff0c;为了减低时间复杂度&#xff0c;所以采用堆排序 import java.security.Key; import java.util.Scanner;public class FindKtopElements {public static void main(String[] args) {Scanner scanner new Scanner(System.in);String lin…...

HTML页面配置高德地图,获取位置

HTML页面配置高德地图&#xff0c;获取位置 一、使用情况 1、之前项目用的前后端分离框架&#xff0c;所以用Vue接入的高德地图&#xff0c;自动搜索补全&#xff0c;是请求的后台返回的数据。 2、现在用单体项目&#xff0c;前端是Bootstrap&#xff0c;需要接高德地图&…...

HTTrack

--不破不立 HTTrack 是一个免费开源的网站离线浏览器。通过它可以将整个网站下载到本地的某个目录&#xff0c;包括 html、图片和脚本以及样式文件&#xff0c;并对其中的链接进行重构以便于在本地进行浏览。 1.官网下载地址&#xff1a;https://www.httrack.com/page/2/en/in…...

干货分享|分享一款微软出品的工作效率神器 PowerToys

工具介绍&#xff1a;Microsoft PowerToys 是一组实用工具&#xff0c;可帮助高级用户调整和简化其 Windows 体验&#xff0c;从而提高工作效率。 安装步骤&#xff1a;直接打开微软商店安装即可&#xff0c;并且可以保证下载到最新版本。 功能介绍&#xff1a; 高级粘贴 高级…...

神经网络的线性部分和非线性部分

神经网络的线性部分和非线性部分是其构成中的两个核心元素&#xff0c;它们共同决定了模型的能力和行为。让我们分别看一下这两部分&#xff1a; 1. 线性部分 线性部分通常是指神经网络中的加权和操作。这部分可以用以下形式表示&#xff1a; [ z W \cdot x b ] W 是权重…...

微信支付开发避坑指南

1 微信支付的坑 1.1 不能用前端传递过来的金额 订单的商品金额要从数据库获取&#xff0c;前端只传商品 id。 1.2 交易类型trade type字段不要传错 v2版API&#xff0c;不同交易类型&#xff0c;要调用的支付方式也不同。 1.3 二次签名 下单时&#xff0c;在拿到预支付交…...

Qt5.4.1连接odbc驱动操作达梦数据库

Qt5.4.1连接odbc驱动操作达梦数据库 1 环境介绍2 Qt5.4.1 安装2.1 图形化界面安装Qt5.4.12.2 配置Qt5.4.1 环境变量2.3 Qt5.4.1 生成 libqsqlodbc.so 并配置2.3.1 生成Makefile2.3.2 查看 libqsqlodbc.so 文件并配置 3 配置Qt测试用例4 达梦数据库学习使用列表 1 环境介绍 CPU…...

计算机组成原理(第一课)

计算机系统概述 1.发展史 摩尔定律&#xff1a;集成电路上可以容纳的晶体管数目在大约每经过18个月到24个月便会增加一倍 2.操作系统组成 存储程序程序控制 五个部分记住&#xff1a; 输入输出功能 I/O 记忆功能 访问 计算功能 计算 判断功能 判断 自我控制功能 自我控制…...

计算机网络练级第一级————认识网络

目录 网络搁哪&#xff1f; 网络的发展史&#xff08;了解&#xff09; 独立模式&#xff1a; 网络互联&#xff1a; 局域网时期&#xff1a; 广域网时期&#xff1a; 什么是协议 TCP/IP五层/四层模型 用官话来说&#xff1a; 我自己的话来说 第一层应用层&#xff1…...

Java基于微信小程序的家庭财务管理系统,附源码

博主介绍&#xff1a;✌Java徐师兄、7年大厂程序员经历。全网粉丝13w、csdn博客专家、掘金/华为云等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb; 不…...

P2343 宝石管理系统

不会写平衡树怎么办&#xff0c;可以用STL的vector或者是pb_ds&#xff0c;这个东西太乱&#xff0c;还是STL好用 #include<bits/stdc.h> using namespace std; int read() {int x 0, f 1;char ch getchar();while (ch < 0 || ch > 9) {if (ch -) f -1;ch g…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...