《TCP/IP网络编程》(第十二章)I/O复用(1)

本章将讨论实现并发服务器的第二种办法,基于I/O复用的服务器端构建

I/O复用它允许单个进程或线程同时处理多个输入/输出(I/O)操作,而无需为每个I/O操作创建一个独立的线程或进程。这种技术可以显著提高应用程序的效率和性能,特别是在需要处理大量并发连接的场景下。

1.多进程服务器端的缺点

基于进程的并发服务器在创建进程时,需要付出极大的代价,因为需要大量的运算和内存空间,而且由于每个进程具有独立的内存空间,相互间交换数据的方法也很复杂。
如果使用I/O复用技术,则可以在不创建进程的情况下同时向多个客户端进行服务。

2.基于I/O复用的服务器端

在这里插入图片描述
上图左边时多进程服务器端模型,右边是I/O复用服务器端模型,可以看出后者无论连接多少个客户端,提供服务的进程只有1个

3.理解select()函数

select() 函数是一种用于I/O复用的系统调用,它允许程序同时监视多个文件描述符(包括套接字),以确定哪些文件描述符已经准备好进行读取或写入操作。select() 函数在Linux系统和Windows系统中都支持,下面是以Linux系统为例,Windows系统示例放在最后。

select()函数基本语法

//发生错误时返回-1; 
//发生关注的事件返回时,返回该事件的文件描述符(大于0)
int select(
int maxds, //设置位监视的文件描述符中最大的描述符加1。例如,如果你监视的文件描述符范围是0到5,则maxfds应该设置为6。
fd_set *readfds, //将所有关注“是否有可读数据”的文件描述符注册到fd_set,并传递其地址值
fd_set *writefds,//将所有关注“是否有可写数据”的文件描述符注册到fd_set,并传递其地址值
fd_set *exceptfds, //将所有关注“是否发生异常”的文件描述符注册到fd_set,并传递其地址值
struct timeval *timeout//设置select() 调用的超时时间,为了防止调用select()函数后,陷入无限阻塞
);

//struct timeval的结构体定义
struct timeval{
long tv_sec;    //秒数
long tv_usec;   //毫秒数
}

select()函数的调用过程

select()函数的调用流程如下图所示,本文将逐步介绍

在这里插入图片描述

  1. 设置文件描述符: select()可以监视多个文件描述符,将需要监视的文件描述符集中为一个集合fd_set,集中时也要按照读、写、异常进行分为三类,fd_set结构如下图所示:
    在这里插入图片描述
    设置为1则代表时监视对象,所以上图中fd1和fd3的是监视对象。在fd_set变量中用下列宏进行操作:
FD_ZERO(fd_set* fdset);          //将所有fd_set变量的所有位设置位0
FD_SET(int fd, fd_set* fdset);   //将fd_set中指定变量的位设置为1
FD_CLR(int fd, fd_set* fdset);   //将fd_set中指定变量的位设置为0
FD_ISSET(int fd, fd_set* fdset); //如果文件描述符在集合中,返回非零值;如果不在集合中,返回0。

在这里插入图片描述

  1. 指定监视范围:select() 函数中的第一个参数maxds, 要监视的文件描述符中最大的描述符加1。例如,如果你监视的文件描述符范围是0到5,则maxfds应该设置为6,因为文件描述分值是从0开始

  2. 设置超时: 如果监视的文件描述符一直没有变化,则会陷入阻塞状态,所以需要设置超时时间,告知服务器超时消息。将秒数填入tv_sec,将毫秒数填入tv_usec

  3. 调用select()函数: 调用 select() 函数,函数会阻塞,直到有文件描述符发生变化或者超时。

  4. 查看调用结果: 返回-1则发生错误;返回一个整数值,则代表有多少个文件描述符准备好了I/O操作,可以进行读取操作了,下图是变化
    在这里插入图片描述
    调用函数前,告诉select()函数,需要监视fd1、fd2、fd3,当调用函数后,首先是将监视的文件描述符的位初始化为0,然后监视到fd1和fd3发生变化,所以fd1和fd3的位又变成了1。

③select()函数示例

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/select.h>

int main(){
    fd_set reads,temps;// 定义文件描述符集合,reads用于存储关注是否可读的文件描述符,temps用于存储select函数返回时准备好的文件描述符
    int result,str_len;// result用于存储select函数的返回值,str_len用于存储读取的字节数
    char buff[1024];
    struct timeval timeout;// 定义一个timeval结构,用于设置select函数的超时时间

    FD_ZERO(&reads);// 清空reads集合
    FD_SET(0,&reads);// 将文件描述符为0的设置为监视状态,文件描述符0通常代表标准输入(stdin),它是一个特殊的文件描述符,用于从键盘接收输入。

    while (1)
    {
        temps=reads;/// 复制reads集合到temps集合
        timeout.tv_sec=5;
        timeout.tv_usec=0;
        result=select(1,&temps,0,0,&timeout);//1表示有1个文件被监视,temps表示被监视“是否可读”的文件描述符集合,0表示“不关注可写”文件描述符,0表示“不关注异常”文件描述符,timeout表示超时时间

        if(result==-1){// 如果select函数返回-1,表示出错
            puts("select error");
            break;
        }
        else if(result==0){// 如果select函数返回0,表示超时
            puts("time-out");
        }
        else{// 如果select函数返回大于0,表示有文件描述符准备好了
            if(FD_ISSET(0,&temps)){// 检查文件描述符0是否在temps集合中
                str_len=read(0,buff,1024);// 从文件描述符0读取数据到buff缓冲区,最多1024字节
                buff[str_len]=0;
                printf("message from console: %s",buff);
            }
        }
    }
    
    
    return 0;
    
}

在这里插入图片描述

键盘输入有被正常监视到,如果不输入,5秒后会输出超时信息

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

多模态中的模态有哪些

“多模态”这个名字中的“模态”&#xff08;modality&#xff09;&#xff0c;指的是不同的数据类型或信息源。在多模态大模型中&#xff0c;常见的模态包括&#xff1a; 文本模态&#xff1a; 包括自然语言文本、语音识别文本等。 图像模态&#xff1a; 指图像数据&#xff…

SEO之核心关键词(二)

初创企业或者需要建站的朋友看以下两篇文章&#xff0c;谢谢支持&#xff1a; 我给不会敲代码又想搭建网站的人建议新手上云 &#xff08;接上一篇。。。。&#xff09; 4、查询搜索次数 经过自己及朋友、同事的头脑风暴和检查竞争对手网站之后&#xff0c;再到Google 关键词…

力扣232. 用栈实现队列(两栈实现队列)

Problem: 232. 用栈实现队列 文章目录 题目描述思路Code 题目描述 思路 利用两个栈&#xff0c;一个入栈一个出栈搭配着实现队列的相关操作&#xff1a; 1.创建两个栈stack1和stack2&#xff1b; 2.void push(int x):将要入队的元素先入栈stack1&#xff1b; 3.int pop()&…

Vue3中点击关闭按钮后清除 el-table 表单内容

Vue3中点击关闭按钮后清除 el-table 表单内容 一、前言1、关闭事件2、清除函数实现3、具体代码 一、前言 在 Vue 3 中&#xff0c;通过使用 Element UI 的 el-table 组件来展示表格数据是一种常见的做法。有时候&#xff0c;当用户点击关闭按钮后&#xff0c;我们希望能够清除…

寒冬来了,字节跳动开启裁员新模式。。

大家好&#xff0c;我是白露啊。 不得不说&#xff0c;字节跳动还是真的会搞事啊。 最近一段时间&#xff0c;字节搞出了一个裁员新模式&#xff1a;“细水长流”。这个寓意和“财&#xff08;裁&#xff09;源&#xff08;员&#xff09;广进”计划差不多了&#xff0c;只不…

Docker安装Nginx 并实现通过nginx部署静态网址

Docker镜像就是一个只读的模板&#xff0c;可以用来创建Docker容器。 例如&#xff1a;一个镜像可以包含一个完整的centos操作系统环境&#xff0c;里面仅安装了mysql、nginx等或用户需要的其他应用程序。 Docker提供了一个非常简单的机制来创建镜像或者更新现有的镜像&#…

马斯克的 xAI 帝国!60亿融资背后的超级布局?

在全球科技竞技场&#xff0c;每个重大融资事件都是对行业格局的一次重塑。近日&#xff0c;埃隆马斯克的人工智能初创企业 xAI 成功完成了一轮规模空前的融资——60亿美元&#xff0c;此举无疑在业界投下了一枚震撼弹&#xff0c;标志着 AI 领域内一场新的竞赛拉开了序幕。 …

rk3568_mutex

文章目录 前言1、什么是mutex?1.1mutex互斥体API函数二、实验2.1实验目的2.2源码2.3结果图前言 本文记录的是rk3568开发板基础上做的mutex实验 1、什么是mutex? mutex是互斥体,它是比信号量semaphore更加专业的机制。 在我们编写Linux驱动的时候遇到需要互斥的地方建议使用…

【Unity程序】Unity游戏开发中常用的设计模式【一】

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

安全性基础知识

安全性基础知识 导航 文章目录 安全性基础知识导航一、网络攻击二、两类密码体制-对称密钥密码体制网络安全内容 三、数字签名与信息摘要四、数字信封五、PKI六、防火墙技术七、入侵检测系统八、计算机病毒九、常见的防病毒软件十、网络安全协议 一、网络攻击 二、两类密码体制…

解读makefile中的.PHONY

在 Makefile 中&#xff0c;.PHONY 是一个特殊的目标&#xff0c;用于声明伪目标&#xff08;phony target&#xff09;。伪目标是指并不代表实际构建结果的目标&#xff0c;而是用来触发特定动作或命令的标识。通常情况下&#xff0c;.PHONY 会被用来声明一组需要执行的动作&a…

accelerate在pycham中执行的方法

1. 简介 通常情况下我们在pycharm中默认执行python.exe xxx.py&#xff0c;在命令行中执行accelerate xxx.py。 下面介绍如何在pycharm中执行accelerate的方法&#xff0c;主要目的是便于后续的代码调试。 2. 内容 第一步&#xff0c;运行->编辑配置&#xff1a; 第二步…

GTD时间管理法

Part 1. What is GTD? | 什么是GTD&#xff1f; GTD is a framework that enhances focus and productivity. Through techniques such as capturing all tasks in a trusted system and breaking down complex projects into actionable items, GTD allows individuals to co…

【项目教程】FFmpeg+SDL2实现视频播放器

一、前言 学习ffmpeg和sdl&#xff0c;并编写一个视频播放器&#xff0c;是一个很好的音视频开发项目。 虽然关于视频播放器的原理已经有很多人在博客中进行了讲解&#xff0c;但是很多人不提供视频和代码&#xff0c;这也是我写这篇博客的主要原因。 二、在视频播放器中&am…

高效编写大模型 Prompt 提示词,解锁 AI 无限创意潜能

随着 ChatGPT 的出现&#xff0c;AI 成为新的焦点&#xff0c;有人说过“未来 50%的工作将是提示词工作”&#xff0c;目前很多公司也在开始招聘 Prompt 提示词工程师。Prompt&#xff08;提示词&#xff09;成为了连接创意与技术的桥梁&#xff0c;它不仅是简单的指令&#xf…

NSSCTF中的pop、babyupload、cve版本签到、奇妙的MD5、easy_html

目录 [SWPUCTF 2021 新生赛]pop [NISACTF 2022]babyupload ​编辑[GKCTF 2020]cve版签到 [SWP5UCTF 2022 新生赛]奇妙的MD5 [HNCTF 2022 Week1]easy_html 今日总结&#xff1a; [SWPUCTF 2021 新生赛]pop 1.代码审计 <?phperror_reporting(0); show_source("…

dubbo复习:(10)使用tripple协议进行通信

一、pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.…

【探索Java编程:从入门到入狱】Day6

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…

Echarts圆环图偏移后 中心文字居中对齐实现

像上图中这样圆环图并不在div的中间时&#xff0c;中心的文本需要居中展示 一开始用left百分比但数据一旦变长或变短就会偏移 像这样 实在是太不美观了 所以我们这里使用动态的left通过文本的长度来计算 /*** 计算文本宽度* param {String|Number} text* param {String} font*…

修改了vue3 <script setup>留言板

Лунная ночь <template><button class"edit_view_checkbox"><input type"checkbox" v-model"editshowInput" value"编辑" /></button><div class"editshowInput" v-if"editshowI…