4.25 IO多路复用简介 4.26select API介绍 4.27 select代码编写

news2024/9/27 21:24:43

4.25 IO多路复用简介

IO多路复用使得程序能同时监听多个文件描述符,能够提高程序的性能,Linux下实现IO多路复用的系统调用主要有select、poll和epoll。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.26select API介绍

主旨思想:
1、首先构造一个关于文件描述符的列表,将要监听的文件描述符添加到该列表中。
2、调用一个系统函数,监听该列表中的文件描述符,直到这些文件描述符中的一个或者多个进行IO操作时,该函数才返回。
a、这个函数是阻塞的
b、函数对这些文件描述符的检测的操作是由内核完成的
3、在返回时,它会告诉进程有多少(哪些)描述符要进行IO操作。

//sizeof(fd_set)=128字节 1024比特位
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select(int nfds,fd_set *readfds,fd_set *writefds, fd_set *exceptfds,struct timeval *timeout);
  -参数:
  		-nfds:委托内核检测的最大文件描述符的值+1
  		-readfds:要检测文件描述符的读的集合,委托内核检测哪些文件描述符的读的属性
  		  -一般检测读操作
  		  -对应的是对应发送过来的数据,因为读是被动的接收数据,检测的是读缓冲区
  		  -是一个传入传出参数
  		-writefds:要检测的文件描述符的写的集合,委托内核检测哪些文件描述符的写的属性
  		  -委托内核检测写缓冲区是不是还可以写数据(不满就可以写)
  		-exceptfds:检测异常的文件描述符的集合
  		-timeout:设置的超时时间
  		  struct timeval{
  		  		long tv_sec;/*seconds*/
  		  		long tv_usec;/*microseconds*/
  		  };
  		  -NULL:永久阻塞,直到检测到了文件描述符有变化
  		  -tv_sec=0,tv_usec=0,不阻塞
  		  -tv_sec>0 tv_usec>0,阻塞对应的时间
  -返回值:
     - -1:失败
     - >0 n:检测的集合中有n个文件描述符发生了变化

//将参数文件描述符fd对应的标志位设置为0
void FD_CLR(int fd,fd_set *set);

//判断fd对应的标志位是0还是1,返回值:fd对应的标志位的值,0,返回0,1,返回1
int FD_ISSET(int fd,fd_set *set);

//将参数文件描述符fd对应的标志位,设置为1
void FD_SET(int fd,fd_set *set); 

//fd_set一共有1024bit,全部初始化为0
void FD_ZERO(fd_set *set);  		  

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.27 select代码编写

客户端程序

#include <stdio.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int main() {s

    // 创建socket
    int fd = socket(PF_INET, SOCK_STREAM, 0);
    if(fd == -1) {
        perror("socket");
        return -1;
    }

    struct sockaddr_in seraddr;
    inet_pton(AF_INET, "127.0.0.1", &seraddr.sin_addr.s_addr);
    seraddr.sin_family = AF_INET;
    seraddr.sin_port = htons(9999);

    // 连接服务器
    int ret = connect(fd, (struct sockaddr *)&seraddr, sizeof(seraddr));

    if(ret == -1){
        perror("connect");
        return -1;
    }

    int num = 0;
    while(1) {
        char sendBuf[1024] = {0};
        sprintf(sendBuf, "send data %d", num++);
        write(fd, sendBuf, strlen(sendBuf) + 1);

        // 接收
        int len = read(fd, sendBuf, sizeof(sendBuf));
        if(len == -1) {
            perror("read");
            return -1;
        }else if(len > 0) {
            printf("read buf = %s\n", sendBuf);
        } else {
            printf("服务器已经断开连接...\n");
            break;
        }
        // sleep(1);
        usleep(1000);
    }

    close(fd);

    return 0;
}

select程序

#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>

int main() {

    // 创建socket
    int lfd = socket(PF_INET, SOCK_STREAM, 0);
    struct sockaddr_in saddr;
    saddr.sin_port = htons(9999);
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = INADDR_ANY;

    // 绑定
    bind(lfd, (struct sockaddr *)&saddr, sizeof(saddr));

    // 监听
    listen(lfd, 8);

    // 创建一个fd_set的集合,存放的是需要检测的文件描述符
    fd_set rdset, tmp;//需要内核检测的为rdset,tmp为交给内核去操作的文件描述符列表
    FD_ZERO(&rdset);
    FD_SET(lfd, &rdset);
    int maxfd = lfd;

    while(1) {

        tmp = rdset;

        // 调用select系统函数,让内核帮检测哪些文件描述符有数据
        int ret = select(maxfd + 1, &tmp, NULL, NULL, NULL);
        if(ret == -1) {
            perror("select");
            exit(-1);
        } else if(ret == 0) {
            continue;//超时时间到了也没有检测到数据,该处设置永久阻塞,不可能返回值为0
        } else if(ret > 0) {
            // 说明检测到了有文件描述符的对应的缓冲区的数据发生了改变,监听文件描述符lfd
            if(FD_ISSET(lfd, &tmp)) {
                // 表示有新的客户端连接进来了
                struct sockaddr_in cliaddr;
                int len = sizeof(cliaddr);
                int cfd = accept(lfd, (struct sockaddr *)&cliaddr, &len);//接受新的连接,并返回新的通讯文件描述符cfd

                // 将新的文件描述符加入到集合中
                FD_SET(cfd, &rdset);

                // 更新最大的文件描述符
                maxfd = maxfd > cfd ? maxfd : cfd;
            }

            //监听文件描述符lfd,在通讯文件描述符的前端
            for(int i = lfd + 1; i <= maxfd; i++) {
                if(FD_ISSET(i, &tmp)) {
                    // 说明这个文件描述符对应的客户端发来了数据
                    char buf[1024] = {0};
                    int len = read(i, buf, sizeof(buf));
                    if(len == -1) {
                        perror("read");
                        exit(-1);
                    } else if(len == 0) {
                        printf("client closed...\n");
                        close(i);
                        FD_CLR(i, &rdset);
                    } else if(len > 0) {
                        printf("read buf = %s\n", buf);
                        write(i, buf, strlen(buf) + 1);
                    }
                }
            }

        }

    }
    close(lfd);
    return 0;
}

select的缺点

在这里插入图片描述

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

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

相关文章

【高危】Openfire权限绕过漏洞(POC公开)

漏洞描述 Openfire是Java开发且基于XMPP&#xff08;前称Jabber&#xff0c;即时通讯协议&#xff09;的开源实时协作&#xff08;RTC&#xff09;服务器。 在受影响版本中&#xff0c;由于路径验证机制存在缺陷&#xff0c;攻击者可以通过/setup/setup-s/%u002e%u002e/%u002e…

基于Python所写的学生管理系统

点击下方链接获取源码资源&#xff1a; https://download.csdn.net/download/qq_64505944/87950397?spm1001.2014.3001.5503 《学生信息管理系统》程序使用说明 在IDLE中运行《学生信息管理系统》即可进入如图1所示的系统主界面。在该界面中可以选择要使用功能对应的菜单进行…

【编译、链接、装载十四】堆与内存管理

【编译、链接、装载十四】堆与内存管理 一、堆与内存管理1、什么是堆 二、Linux进程堆管理三、Windows进程堆管理Q&A 一、堆与内存管理 相对于栈而言&#xff0c; 堆这片内存面临一个稍微复杂的行为模式&#xff1a; 在任意时刻&#xff0c; 程序可能发出请求&#xff0c;…

请求响应相关知识点

这里写目录标题 请求响应概述 请求postman各种参数的封装以及接收简单参数原始方式springboot方式映射解决参数不匹配小结 实体参数简单的实体参数复杂的实体参数注意点 数组集合参数数组集合总结 日期参数json参数模拟发送注意点服务端注意点 路径参数各个参数总结 响应注解统…

66、基于51单片机超声波测距LCD1602显示报警系统设计(程序+原理图+PCB源文件+Proteus仿真+参考论文+开题报告+任务书+元器件清单等)

前 言 超声波具有指向性强&#xff0c;能量消耗缓慢&#xff0c;在介质中传播的距离较远&#xff0c;因而超声波经常用于距离的测量&#xff0c;如测距仪和物位测量仪等都可以通过超声波来实现。利用超声波检测往往比较迅速、方便、计算简单、易于做到实时控制&#xff0c;并且…

JDK8新特性-中部

文章目录 一、方法引用1.1 为什么要有方法引用?1.1.1 Lambda表达式冗余1.1.2 解决方案 1.2 方法引用的格式1.2 .1 对象::方法名1.2.2 类名::静态方法名1.2.3 类名::引用实例方法1.2.4 类名::构造器1.2.5 数组::构造器 二、Stream API2.1 集合处理的弊端2.2 Steam流式思想概述2…

HttpRunner抓包工具之HttpRunner介绍

HttpRunner简介&#xff1a; HttpRunner 是一款面向HTTP(S) 协议的通用测试框架&#xff0c;只需编写维护一份YAML/JSON 脚本&#xff0c;即可实现自动化测试、性能测试、线上监控、持续集成等多种测试需求。 作者李隆之前是大疆的测试开发工程师&#xff0c;项目起源于大疆内部…

关于数据分析中NumPy,Pandas,看完这一篇基本够了

前言 数据分析是Python的重要应用领域之一&#xff1a;Python在数据分析领域有着广泛的应用&#xff0c;许多数据科学家和分析师使用Python作为主要的数据分析工具。学好数据分析可以让你更好地应用Python来解决实际问题&#xff0c;并提升在数据分析领域的竞争力。 在当今信…

04 todoList案例

React全家桶 一、案例- TODO List 综合案例 功能描述 动态显示初始列表添加一个 todo删除一个 todo反选一个 todotodo 的全部数量和完成数量全选/全不选 todo删除完成的 todo 1.1 静态组件构建 将资料包中的todos_page/index.html中核心代码添加到Todo.jsx文件中&#xff0c;…

高速电路设计系列分享-ADC电源的设计

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 提示&#xff1a;这里可以添加技术概要 如今&#xff0c;在设计人员面临众多电源选择的情况下&#xff0c;为高速ADC设计清洁电源时可能会面临巨大挑战。在利用高效开关电源而非传统LDO的场合&#xff0c;这尤其重要。…

liunx服务器使用selenium

文章目录 前言一、服务器下载google-chrome、chromedriver1、下载chrome2、下载chromedriver 二、安装Xvfb和python库pyvirtualdisplay、selenium1、安装Xvfb2、安装python库pyvirtualdisplay 三、配置好后测试总结 前言 最近在本地windows系统&#xff08;下面简称本地&#…

在线搭建K8S,kubernetes集群v1.23.9,docker支持的最后一个版本

1. 部署环境主机&#xff08;条件说明&#xff09; master 192.168.186.128 CentOS Linux release 7.9.2009 (Core) node1 192.168.186.129 CentOS Linux release 7.9.2009 (Core) node2 192.168.186.130 CentOS Linux release 7.9.2009 (Core)2. 系统初始化-所有节点&am…

探索MediaPipe的人像分割

MediaPipe是Google开源的计算机视觉处理框架&#xff0c;基于TensorFlow来训练模型。图像分割模块提供人像分割、头发分割、多类分割。本文主要探索如何实现人像分割&#xff0c;当然在人像分割基础上&#xff0c;我们可以做背景替换、背景模糊。 目录 一、配置参数与模型 1…

负载均衡 Load Balancing

负载均衡 Load Balancing 数据链路层负载均衡网络层负载均衡应用层负载均衡均衡策略与实现轮询与随机随机权重与加权轮询一致性 hash最少活跃数&#xff08;最少连接数&#xff09; 对于电商平台而言&#xff0c;随着业务的不断发展壮大&#xff0c;网站访问量和数据量也随之急…

什么是堆栈?c语言实现栈上的pop和push操作

什么是堆栈&#xff1f;c语言实现栈上pop和push操作的算法 堆栈&#xff08;stack&#xff09;实现栈上pop和push操作解释 堆栈&#xff08;stack&#xff09; 堆栈&#xff08;stack&#xff09;是一种数据结构&#xff0c;它具有后进先出&#xff08;Last-In-First-Out&…

抖音seo矩阵系统源码开发部署思路

抖音SEO矩阵系统源码开发和部署是一项复杂而又关键的任务。在开发阶段&#xff0c;我们需要根据抖音的搜索规则和算法&#xff0c;结合用户搜索意图和关键词&#xff0c;进行深入的研究和分析&#xff0c;以建立一个优秀的SEO矩阵系统。 在部署方面&#xff0c;我们需要遵循以…

完全零基础,如何学习渗透?

网络渗透这一行&#xff0c;做个脚本小子&#xff0c;使使工具啥的&#xff0c;个把月就学会了&#xff0c;这不难。 很多人把网络渗透简单的理解成就是搞网站&#xff0c;这是大错特错的&#xff01; 不过这也难怪&#xff0c;Web安全那三招两式&#xff0c;最好教也最好学&…

还在找wma格式怎么转换mp3?

在一个遥远的国度里&#xff0c;有一位名叫小芳的歌手&#xff0c;她声音甜美动人&#xff0c;深受人们的喜爱。然而&#xff0c;她的音乐制作团队告诉她&#xff0c;她的歌曲只能以wma格式发布。但是&#xff0c;她的粉丝们大多数使用的是mp3格式的音乐播放器&#xff0c;这让…

【Java】JVM(五)

垃圾回收机制 判断对象的存活 在堆里面存放着几乎所有的对象实例&#xff0c;垃圾回收器在对对进行回收前&#xff0c;要做的事情就是确定这些对象中哪些还是“存活”着&#xff0c;哪些已经“死去”&#xff08;死去代表着不可能再被任何途径使用得对象了&#xff09; 可达…

【pytest学习总结2.3】 - 如何使用固定装置fixtures(2)

目录 2.3.8 使用mark给固定装置传递数据 2.3.9 将固定装置工厂化 2.3.10 参数化固定装置 2.3.11 使用带有参数化固定装置的标记 2.3.12 使用来自固定装置功能中的固定装置 - 模块化 2.3.13 按固定装置实例自动分组测试 2.3.14 在类和模块中使用usefixtures 2.3.15 固定…