day-07 I/O复用(select)

一.I/O复用

(一)基于I/O复用的服务器端

1.多进程服务器

        每次服务都需要创建一个进程,需要大量的运算和内存空间

2.复用

        只需创建一个进程。

3.复用技术在服务器端的应用

 (二)select函数实现服务器端

  • (Linux和Windows平台下均有select函数,所以具有良好移植性)

1.select函数调用过程:

2.select函数示例:(5秒内控制才没有输入,就输出 Timeout ;否则打印输入。)

#include<iostream>
#include<unistd.h>
#include<sys/time.h>
#include<sys/select.h>
using namespace std;
#define BUF_SIZE 30int main(int argc,char *argv[]){fd_set reads,temps;int result,str_len;//fd_set类型是一个文件描述符集合,char buf[BUF_SIZE];//在这里声明了reads和temps两个集合用于I/O复用。struct timeval timeout;FD_ZERO(&reads);//用于清空文件描述符集合。FD_SET(0,&reads);//将标准输入文件描述符添加到集合中while(1){temps=reads;//在每次循环开始时,将temps设置为上一次存有文件描述符的集合reads的副本。timeout.tv_sec=5;//设置超时时间为5秒timeout.tv_usec=0;result=select(1,&temps,0,0,&timeout);调用select函数来等待可读事件就绪或超时发生。if(result==-1){//第一个参数表示要监视的最大文件描述符值加1,cout<<"select() error"<<endl;//第二个参数是指向待检查的文件描述符集合的指针,break;                       //后面的三个参数是输出参数。}else if(result==0)cout<<"Time out"<<endl;else{if(FD_ISSET(0,&temps))//检查输入文件描述符是否就绪{str_len=read(0,buf,BUF_SIZE);buf[str_len]=0;cout<<"message from console: "<<buf<<endl;}}//如果select函数返回-1,表示出现了错误,输出错误信息并跳出循环。//如果select函数返回0,表示超时,输出"Time out"。//如果select函数返回大于0的值,表示文件描述符就绪。//这里通过FD_ISSET宏检查标准输入文件描述符是否在集合中就绪。//如果标准输入文件描述符就绪,调用read函数读取输入内容,并输出到控制台。}return 0;
}

3.实现I/O复用服务器端

#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<sys/time.h>
#include<sys/select.h>
using namespace std;#define BUF_SIZE 100//宏定义了一个缓冲区大小为100的常量。
void error_handling(const  char *buf);int main(int argc,char *argv[]){int serv_sock,clnt_sock;struct sockaddr_in serv_adr,clnt_adr;struct timeval timeout;fd_set reads,cpy_reads;socklen_t adr_sz;int fd_max,str_len,fd_num,i;char buf[BUF_SIZE];if(argc!=2){cout<<"Usage:"<<argv[0]<<endl;exit(1);}serv_sock=socket(PF_INET,SOCK_STREAM,0);//创建套接字memset(&serv_adr,0,sizeof(serv_adr));//将结构体清零serv_adr.sin_family=AF_INET;serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);//设置服务器地址信息、IP地址和端口号serv_adr.sin_port=htons(atoi(argv[1]));if(bind(serv_sock,(struct sockaddr*)&serv_adr,sizeof(serv_adr))==-1)error_handling("bind() error");      //将套接字和指定地址绑定if(listen(serv_sock,5)==-1)//开始监听连接请求error_handling("listen() error");FD_ZERO(&reads);//清空文件描述符集合FD_SET(serv_sock,&reads);//将服务器套接字添加到reads集合中fd_max=serv_sock;//fd_max初始化为服务器套接字的值while(1){//进入主循环cpy_reads=reads;//将reads集合复制过来timeout.tv_sec=5;//超时时间timeout.tv_usec=5000;if((fd_num=select(fd_max+1,&cpy_reads,0,0,&timeout))==-1)break;        //监控文件描述符的状态变化if(fd_num==0)continue;for(i=0;i<fd_max+1;i++){if(FD_ISSET(i,&cpy_reads)){//检查文件描述符是否就绪if(i==serv_sock){//如果是服务器套接字,表示有新的客户端连接请求adr_sz=sizeof(clnt_adr);clnt_sock=accept(serv_sock,(struct sockaddr*)&clnt_adr,&adr_sz);FD_SET(clnt_sock,&reads);if(fd_max<clnt_sock)fd_max=clnt_sock;cout<<"connect client: "<<clnt_sock<<endl;}else{//如果不是服务器套接字,表示已连接的客户端有数据发送过来str_len=read(i,buf,BUF_SIZE);if(str_len==0){FD_CLR(i,&reads);close(i);cout<<"closed client:"<<i<<endl;}elsewrite(i,buf,str_len);}}}}close(serv_sock);return 0;
}void error_handling(const char *buf){cout<<buf<<endl;exit(1);
}

(三)总结 

1.请解释复用技术的通用含义,并说明何为I/O复用。

复用技术指为了提高物理设备的效率,用最少的物理要素传递最多数据时使用的技术。同样,I/O复用是指将需要I/O的套接字捆绑在一起,利用最少限度的资源来收发数据的技术

2.多进程并发服务器的缺点有哪些?如何在I/O复用服务器端中弥补?

多进程并发服务器的服务方式是,每当客户端提出连接要求时,就会追加生成进程。但构建进程是一项非常有负担的工作,因此,向众多客户端提供服务存在一定的局限性。而复用服务器则是将套接字的文件描述符捆绑在一起管理的方式,因此可以一个进程管理所有的I/O操作

3.select函数的观察对象中应包含服务器端套接字(监听套接字),那么应将其包含到哪一类监听对象集合?请说明原因

服务器套接字的作用是监听有无连接请求,即判断接收的连接请求是否存在?应该将其包含到“读”类监听对象的集合中。

4.select函数使用的fd_set结构体在Windows和Linux中具有不同的声明。请说明却别,同时解释存在区别的必然性

Linux的文件描述符从0开始递增,因此可以找出当前文件描述符数量和最后生成的文件描述符之间的关系。但Windows的套接字句柄并非从0开始,并且句柄的整数值之间并无规律可循,因此需要直接保存句柄的数组和记录句柄数的变量。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

03-基础例程3

基础例程3 01、外部中断 ESP32的外部中断有上升沿、下降沿、低电平、高电平触发模式。 实验目的 使用外部中断功能实现按键控制LED的亮灭 按键按下为0。【即下降沿】 * 接线说明&#xff1a;按键模块-->ESP32 IO* (K1-K4)-->(14,27,26,25)* * …

软件测试Day6|接口测试

学习流程 接口测试流程 需求分析和评审–接口文档分析–编写测试用例–测试用例设计及评审–测试脚本构建–执行测试用例–缺陷管理和回归–测试报告和总结计网基础&#xff08;URL、请求、响应&#xff09; 接口文档解析 拿到一个项目接口之后&#xff0c;先测试业务接口还是…

抽象轻松的C语言

#include <stdio.h> /* 预处理指令*/ /* 函数 */ int main() {int log 3.14;printf("hello word * %d\n easy", log);getchar();/* 获取键盘输入的字母&#xff0c;在这个程序中的作用是防止程序瞬间关闭 */return 0; } 上一篇说过&#xff0c;C程序是C语言的…

21.4 CSS 盒子模型

1. 边框样式 border-style属性: 指定元素的边框样式.常用属性值: - none: 无边框(默认值). - solid: 实线边框. - dotted: 点状边框. - dashed: 虚线边框. - double: 双线边框. - groove: 凹槽状边框. - ridge: 脊状边框. - inset: 内阴影边框. - outset: 外阴影边框.这些值可…

「MySQL-02」数据库的操纵、备份、还原和编码规则

目录 一、库操作 1. 创建数据库 2. 查看所有数据库 3. 删除数据库 4. 修改数据库 5. 进入一个数据库 二、查看和设置数据库的编码规则 1. MySQL的两个编码规则&#xff1a;字符集和校验规则 2. 查看MySQL当前使用的字符集以及校验规则 3. 查看MySQL支持的所有字符集 4. 查看MyS…

肖sir__linux详解__002(系统命令)

linux系统命令 1、df 查看磁盘使用情况 &#xff08;1&#xff09;df 查看磁盘使用情况&#xff08;按kb单位显示&#xff09; &#xff08;2&#xff09;df -h 按单位显示磁盘使用情况 2、top 实时查看动态进程 &#xff08;1&#xff09;top 详解&#xff1a; 第一行&…

为什么要学习C++

操作系统历史 UINX操作系统诞生之初是用汇编语言编写的。随着UNIX的发展&#xff0c;汇编语言的开发效率成为一个瓶颈。寻找新的高效开发语言成为UNIX开发者需要解决的问题。当时BCPL语言成为了当时的选择之一。Ken Thomposn对BCPL进行简化得到了B语言。但是B语言不是直接生成…

【AWS实验】 配置中转网关及对等连接

文章目录 实验概览目标实验环境任务 1&#xff1a;查看网络拓扑并创建基准任务 2&#xff1a;创建中转网关任务 3&#xff1a;创建中转网关挂载任务 4&#xff1a;创建中转网关路由表任务 4.1&#xff1a;创建路由表关联任务 4.2&#xff1a;创建路由传播 任务 5&#xff1a;更…

Android JNI系列详解之ndk-build工具的使用

一、Android项目中使用ndk-build工具编译库文件 之前介绍过CMake编译工具的使用&#xff0c;今天介绍一种ndk自带的编译工具ndk-build的使用。 ndk-build目前主要有两种配置使用方式&#xff1a; 如上图所示&#xff0c;第一种方式是Android.mkApplication.mkgradle的方式生成…

SpringBoot初级开发--服务请求(GET/POST)所有参数的记录管理(8)

服务端在定位错误的时候&#xff0c;有时候要还原现场&#xff0c;这就要把当时的所有入参参数都能记录下来&#xff0c;GET还好说&#xff0c;基本NGINX都会记录。但是POST的请求参数基本不会被记录&#xff0c;这就需要我们通过一些小技巧来记录这些参数&#xff0c;放入日志…

C++ struct 笔记(超级详细)

今日碎碎念&#xff1a;我在学C语言时经常用到结构体struct&#xff0c;之后在写C程序时遇到在struct中定义构造函数和成员函数的情况&#xff0c;这在c语言中是从未遇到过的&#xff0c;觉得奇怪&#xff0c;想到之前并没有真正系统学习C里的struct&#xff0c;有必要今天详细…

企业架构LNMP学习笔记8

1、 运维人员需要考虑安全性、稳定性。 安装&#xff1a; 解压进入到目录&#xff1a; shell > tar zxf php-7.2.12.tar.gz shell > cd php-7.2.12 安装依赖软件&#xff1a; yum -y install libxml2-devel libjpeg-devel libpng-devel freetype-devel curl-devel op…

uniapp 微信小程序 获取用户头像和昵称

一、背景 自2022年10月25日后&#xff0c;小程序 wx.getUserProfile 接口 被收回&#xff0c;通过 wx.getUserInfo 接口获取用户头像将统一返回默认灰色头像&#xff0c;昵称将统一返回 “微信用户”。如需获取用户头像昵称&#xff0c;可以手动获取&#xff0c;具体步骤&…

Java单元测试及常用语句 | 京东物流技术团队

1 前言 编写Java单元测试用例&#xff0c;即把一段复杂的代码拆解成一系列简单的单元测试用例&#xff0c;并且无需启动服务&#xff0c;在短时间内测试代码中的处理逻辑。写好Java单元测试用例&#xff0c;其实就是把“复杂问题简单化&#xff0c;建单问题深入化“。在编写的…

Shell脚本练习——系统应用相关

显示系统信息 [rootwenzi data]#cat systemInfo.sh #/bin/bash RED"\E[1;31m" GREEN"\E[1;32m" END"\E[0m" echo -e "$GREEN----------------------Host systeminfo--------------------$END" echo -e "HOSTNAME: $REDho…

没有 JavaScript 计时器的自动播放轮播 - CSS 动画

先看效果&#xff1a; 再看代码&#xff08;查看更多&#xff09;&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>计时器</title><style>* {padding: 0;margin: 0;box-siz…

WorkManager的基本使用

目录 一、WorkManager概述1. WorkManager的作用&#xff1a;2. WorkManager的各个角色 二、依赖库的导入三、WorkManager几种基本使用1. 单一任务的执行2. 数据 互相传递3. 多个任务 顺序执行4. 重复执行后台任务5. 约束条件6. 证明 app被杀掉之后&#xff0c;还在后台执行 四、…

Linux - Docker 安装使用 常用命令 教程

Docker 官方文档地址: Get Started | Docker 中文参考手册: https://docker_practice.gitee.io/zh-cn/ 1.什么是 Docker 1.1 官方定义 最新官网首页 # 1.官方介绍 - We have a complete container solution for you - no matter who you are and where you are on your contain…

[SWPUCTF 2022]——Web方向 详细Writeup

SWPUCTF 2022 ez_ez_php 打开环境得到源码 <?php error_reporting(0); if (isset($_GET[file])) {if ( substr($_GET["file"], 0, 3) "php" ) {echo "Nice!!!";include($_GET["file"]);} else {echo "Hacker!!";} }e…