C++学习之服务器EPOLL模型、处理客户端请求、向客户端回复数、向客户端发送文件
目录
1.启动epoll模型
2.和客户端建立新连接
3.接受客户端Http请求数据
4.代码回顾从接受的数据中读出请求行
5.请求行解析
6.正则表达式以及匹配
7.解析请求行以及后续处理
8.对path处理说明
9.如何回复响应数据
10.对文件对应content-type如何查询
11.服务器处理流程梳理
12.和客户端断开连接处理
13.http请求处理流程回顾
14.发送状态行和响应头
15.根据文件获取content-type和发送文件
16.程序调试和访问文件测试
1.启动epoll模型
需求:
客户端: - 浏览器
通IP和端口访问服务器上的某个目录或者文件
- 访问目录:
// 192.168.1.100:8888 这个服务器提供了一个资源目录, 里边有子目录hello/world
- 192.168.1.100:8888/hello/world/
- 访问文件:
//192.168.1.100 这个服务器提供了一个资源目录,里边有子目录hello, 这里边有文件 a.html
192.168.1.100:8888/hello/a.html
服务器: - C语言
- 客户端的是浏览器: 使用的协议必须是http
- 服务器提供什么功能?
- 接受多客户端的连接
- 应用程层使用http, 传输层协议tcp
- 基于epoll写 / 基于libev


2.和客户端建立新连接
- 在epoll中
- 接受新连接 -> 客户端(浏览器)
- 通信
- 接收浏览器发送过来 http 请求
- 浏览器只给服务器发送get请求
- 判断是不是get请求
- 判断客户端访问的是不是服务器的某个资源目录
- 需要将这个目录中的所有的文件信息发送给浏览器
- 回复数据的时候, 需要使用http响应消息对回复的数据进行包装
- 要保证的数据是什么格式?
- 回复一个动态网页
- 是一个列表 -><table>
- 判断客户端访问的是不是服务器资源目录中的某个文件
- 服务器需要将这个文件发送给浏览器
- 回复数据的时候, 需要使用http响应消息对回复的数据进行包装

3.接受客户端Http请求数据
- ## sscanf函数
```c
// 函数原型
// 将参数str的字符串根据参数format字符串来转换并格式化数据,转换后的结果存于对应的参数内。
sscanf(const char *str, const char *format, ...)。
具体功能如下:
(1)根据格式从字符串中提取数据。如从字符串中取出整数、浮点数和字符串等。
(2)取指定长度的字符串
(3)取到指定字符为止的字符串
(4)取仅包含指定字符集的字符串
(5)取到指定字符集为止的字符串
sscanf可以支持格式字符%[]:
(1)-: 表示范围,如:%[1-9]表示只读取1-9这几个数字 %[a-z]表示只读取a-z小写字母,类似地 %[A-Z]只读取大写字母
(2)^: 表示不取,如:%[^1]表示读取除'1'以外的所有字符 %[^/]表示除/以外的所有字符
(3),: 范围可以用","相连接 如%[1-9,a-z]表示同时取1-9数字和a-z小写字母
(4)原则:从第一个在指定范围内的数字开始读取,到第一个不在范围内的数字结束%s 可以看成%[] 的一个特例 %[^ ](注意^后面有一个空格!)
```

4.代码回顾从接受的数据中读出请求行
```c
const char *s = "http://www.baidu.com:1234";
char protocol[32] = { 0 };
char host[128] = { 0 };
char port[8] = { 0 };
sscanf(s,"%[^:]://%[^:]:%[1-9]",protocol,host,port);
printf("protocol: %s\n",protocol);
printf("host: %s\n",host);
printf("port: %s\n",port);
///
sscanf("123456 abcdedf", "%[^ ]", buf);
printf("%s\n", buf);
结果为:123456
///
sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf);
printf("%s\n", buf);
结果为:123456abcdedf
///
sscanf("123456abcdedfBCDEF", "%[^A-Z]", buf);
printf("%s\n", buf);
结果为:123456abcdedf

5.请求行解析
## scandir函数
```c
// 头文件
#include <dirent.h>
//函数定义
/*
函数scandir扫描dir目录下以及dir子目录下满足filter过滤模式的文件,返回的结果是compare函数经过排
序的,并保存在 namelist中。注意namelist是通过malloc动态分配内存的,所以在使用时要注意释放内存。
alphasort和versionsort 是使用到的两种排序的函数。
当函数成功执行时返回找到匹配模式文件的个数,如果失败将返回-1。
*/
int scandir(const char *dir,struct dirent **namelist,int (*filter)(const void *b),
int (* compare)(const struct dirent **, const struct dirent **));
int alphasort(const void *a, const void *b);
int versionsort(const void *a, const void *b);
```

6.正则表达式以及匹配


7.解析请求行以及后续处理
> 超文本标记语言(**H**yper **T**ext **M**arkup **L**anguage),标准通用标记语言下的一个应用。HTML 不是一种编程语言,而是一种标记语言 (markup language),是网页制作所必备的。
>
> 超文本就是指页面内可以包含图片、链接,甚至音乐、程序等非文字元素。
>
> 超文本标记语言的结构包括**“**头”部分(英语:Head)、和“主体”部分(英语:Body),其中“头”部提供关于网页的信息,“主体”部分提供网页的具体内容。
- html 特点
- 语法非常简洁、比较松散,以相应的英语单词关键字进行组合
- 有很多标签, 不同标签表达的意义不同, 每个标签的功能都是固定不变的
- 不按照标准格式写网页, 也可以被解析
- html标签不区分大小写
- 大多数标签是成对出现的, 有开始, 有结束
- <html></html>
- 特殊的单标签: <img> <hr> <br>
- 成对的标签
- 不成对出现的称之为短标签
- html文件命名
- `xxx.html`
- `xxx.htm`

8.对path处理说明
- html文件命名
- `xxx.html`
- `xxx.htm`
- 注释
```html
<!-- 这是一个注释 -->
```
- 结构
```html
<html> <!-- 根标签, 代表网页的开始 -->
<head>
<!-- tab页的标题, 和网页的一些属性设置 -->
<title>握手标题</title>
</head>
<body>
<!-- 在网页中显示的内容 -->
</body>
</html>
```


9.如何回复响应数据
## 1.2 文字和标题标签
```html
<!-- 标题标签 , h1最大的, h6最小的 -->
<h1></h1>
<h2></h2>
<h3></h3>
......
<h6></h6>
<!-- 文字 , 习惯上将属性的值放到单引号, 或者双引号中 -->
<font color="blue" size="5">hello,world</font>
属性:
color: 文字颜色
□ 表示方式:
® 英文单词: red green blue......
® 使用16进制的形式表示颜色: #ffffff
size: 文字大小
□ 范围 1 -- 7
® 1最小, 7最大
<!-- 段落 自动换行 -->
<p></p>
<!-- 换行 单标签, 末尾有没有/都可以 -->
<br/> or <br>
<!-- 水平线 单标签, 末尾有没有/都可以 -->
<hr/> or <hr>
<!-- 文本格式 -->
加粗:
<strong></strong>
<b></b>
文本倾斜标签
<em></em>
<i></i>
删除线标签
<del></del>
<s></s>
下划线标签
<ins></ins>
<u></u>
```

10.对文件对应content-type如何查询
```http
POST / HTTP/1.1
Host: 192.168.1.8:6789
Connection: keep-alive
Content-Length: 98
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: null
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.106 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
username=subwen%40qq.com&phone=1111111&email=sub%40qq.com&date=2020-01-01&sex=male&class=1&rule=on

11.服务器处理流程梳理
第 2-9 行: 响应头(消息报头)
- Content-Type: 服务器给客户端回复的数据块的格式 == http响应第四部分的数据块格式
- text/plain; ==> 纯文本
- charset=iso-8859-1 ==> 数据的字符编码
- iso-8859-1 ==> 不支持中文
- utf8: 支持中文
- Content-Length: 服务器给客户端回复的数据块的长度 == http响应第四部分的数据块字节数
- 对应的value值必须是正确的数值
- 如果不知道数据块的字节数, 可以指定-1
第 11-16 行: 服务器给客户端回复的响应数据


12.和客户端断开连接处理
1. http状态码
> 状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别:
>
> - 1xx:指示信息--表示请求已接收,继续处理
> - 2xx:成功--表示请求已被成功接收、理解、接受
> - 3xx:重定向--要完成请求必须进行更进一步的操作
> - 4xx:客户端错误--请求有语法错误或请求无法实现
> - 5xx:服务器端错误--服务器未能实现合法的请求
> 常见状态码:
>
> - 200 OK 客户端请求成功
> - 400 Bad Request 客户端请求有语法错误,不能被服务器所理解
> - 401 Unauthorized 请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
> - 403 Forbidden 服务器收到请求,但是拒绝提供服务
> - 404 Not Found 请求资源不存在,eg:输入了错误的URL
> - 500 Internal Server Error 服务器发生不可预期的错误
> - 503 Server Unavailable 服务器当前不能处理客户端的请求,一段时间后可能恢复正常

13.http请求处理流程回顾
```c
/*
客户端: 浏览器
- 通过浏览器访问服务器:
- 访问方式: 服务器的IP地址:端口
- 应用层协议使用: http, 数据需要在浏览器端使用该协议进行包装
- 响应消息的处理也是浏览器完成的 => 程序猿不需要管
- 客户端通过url访问服务器资源
- 客户端访问的路径:
1. http://192.168.1.100:8989/ 或者 http://192.168.1.100:8989
- 访问服务器提供的资源目录的根目录
- 并不是服务器上的 / 目录
- 这个目录根据服务器端的描述应该是: /home/robin/luffy 目录
- 请求行:
GET / HTTP/1.1
2. http://192.168.1.100:8989/a.txt
- 端口后边的/代表服务器的资源根目录
- 在服务器端路径: /home/robin/luffy 目录
- 客户端要访问服务器上的a.txt的文件
- a.txt 这个文件在服务器提供的资源目录中
- 服务器上的路径: /home/robin/luffy/a.txt
- 请求行:
GET /a.txt HTTP/1.1
3. http://192.168.1.100:8989/hello/a.txt
- http://192.168.1.100:8989: 服务器地址
- /hello/a.txt
- /: 服务器端提供的资源根目录
- hello: 资源根目录的子目录
- a.txt: 在hello目录中
- 请求行:
GET /hello/a.txt HTTP/1.1
4. http://192.168.1.100:8989/hello/wrold/
- http://192.168.1.100:8989: 服务器地址
- /hello/world/
- /: 服务器端提供的资源根目录
- hello: 资源根目录的子目录
- world/: 如果world后边有/代表这是一个目录, 这个目录在hello目录中
- 请求行:
GET /hello/world/ HTTP/1.1
*/
14.发送状态行和响应头
// 服务器端处理的伪代码
int main()
{
// 1. 创建监听的fd
socket();
// 2. 绑定
bind();
// 3. 设置监听
listen();
// 4. 创建epoll模型
epoll_create();
epoll_ctl();
// 5. 检测
while(1)
{
epoll_wait();
// 监听的文件描述符
accept();
// 通信的
// 接收数据->http请求消息
recvAndParseHttp();
}
return 0;
}

15.根据文件获取content-type和发送文件
```http
HTTP/1.1 200 Ok
Server: micro_httpd
Date: Fri, 18 Jul 2014 14:34:26 GMT
Content-Type: text/plain; charset=iso-8859-1 (必选项)
Content-Length: 32
Location: https://www.biadu.com
Content-Language: zh-CN
Last-Modified: Fri, 18 Jul 2014 08:36:36 GMT
Connection: close
#include <stdio.h>
int main(void)
{
printf("hello world!\n");
return 0;
}
```
16.程序调试和访问文件测试

相关文章:
C++学习之服务器EPOLL模型、处理客户端请求、向客户端回复数、向客户端发送文件
目录 1.启动epoll模型 2.和客户端建立新连接 3.接受客户端Http请求数据 4.代码回顾从接受的数据中读出请求行 5.请求行解析 6.正则表达式以及匹配 7.解析请求行以及后续处理 8.对path处理说明 9.如何回复响应数据 10.对文件对应content-type如何查询 11.服务器处理流…...
BUUCTF-web刷题篇(17)
26.BabyUpload 源码:https://github.com/imaginiso/GXY_CTF/tree/master/Web/babyupload 查看题目源码: 写着:SetHandler application/x-httpd-php 通过源码可以看出这道文件上传题目主要还是考察.htaccess配置文件的特性,倘若…...
国网B接口协议调阅实时视频接口流程详解以及检索失败原因(电网B接口)
文章目录 一、B接口协议调阅实时视频接口介绍B.6.1 接口描述B.6.2 接口流程B.6.3 接口参数B.6.3.1 SIP头字段B.6.3.2 SIP响应码B.6.3.3 SDP参数定义B.6.3.4 RTP动态Payload定义 B.6.4 消息示例B.6.4.1 调阅实时视频请求B.6.4.2 调阅实时视频请求响应 二、B接口调阅实时视频失败…...
windows11下pytorch(cpu)安装
先装anaconda 见最下方 Pytorch 官网:PyTorch 找到下图(不要求版本一样)(我的电脑是集显(有navdia的装gpu),装cpu) 查看已有环境列表 创建环境 conda create –n 虚拟环境名字(…...
NVR接入录像回放平台用EasyCVR打造地下车库安防:大型商居安全优选方案
一、背景分析 随着居民生活品质的提升,大型商业建筑和住宅小区纷纷配套建设地下停车库。但是地下车库盗窃、失火、恶意毁坏车辆、外部人员随意进出等事件频发,部署视频监控系统成为保障地下车库的安全关键举措。 目前,很多商业和住宅都会在…...
玻璃期货数据下载与分析:Python金融实战分享
期货数据下载与分析:Python实战分享 引言 在金融市场中,期货分析是一项重要的工作,而获取准确且及时的数据是进行有效分析的基础。今天,我们将深入探讨一段使用Python编写的代码,该代码用于从郑州商品交易所…...
excel常见错误包括(#N/A、#VALUE!、#REF!、#DIV/0!、#NUM!、#NAME?、#NULL! )
目录 1. #N/A2. #VALUE!3. #REF!4. #DIV/0!5. #NUM!6. #NAME?7. #NULL!8.图表总结 在 Excel 中,可能会遇到以下常见的错误值,每个都有特定的含义和成因: 1. #N/A 含义: 表示“Not Available”(不可用)。…...
乾元通渠道商中标川藏铁路西藏救援队应急救援装备项目
乾元通渠道商中标川藏铁路西藏救援队应急救援装备项目,项目内通信指挥车基于最新一代应急指挥车解决方案打造,配合乾元通自研的车载多链路聚合路由及系统,主要用途为保障应急通讯,满足任务执行时指挥协调、通信联络及数据传输的要…...
数学知识——矩阵乘法
使用矩阵快速幂优化递推问题 对于一个递推问题,如递推式的每一项系数都为常数,我们可以使用矩阵快速幂来对算法进行优化。 一般形式为: F n F 1 A n − 1 F_nF_1A^{n-1} FnF1An−1 由于递推式的每一项系数都为常数,因此对…...
左右开弓策略思路
一、策略概述 本策略是一种基于多种技术指标的复杂交易策略,包括自定义指标计算、过滤平滑处理以及交易信号生成。 该策略通过不同的交易平台代码段实现,旨在通过分析历史价格数据来预测未来价格走势,并据此生成交易信号。 二、主要技术指标…...
将jar包制作成deb一键安装包
文章目录 准备环境准备deb包结构构建Deb包测试安装常用操作命令 本文介绍如何将java运行环境、jar程序一起打包成一个deb格式的安装包,创建桌面图标,通过点击图标可使用系统自带浏览器快捷访问web服务的URL,同时注册服务并配置好开机自启。 准…...
Java 常用安全框架的 授权模型 对比分析,涵盖 RBAC、ABAC、ACL、基于权限/角色 等模型,结合框架实现方式、适用场景和优缺点进行详细说明
以下是 Java 常用安全框架的 授权模型 对比分析,涵盖 RBAC、ABAC、ACL、基于权限/角色 等模型,结合框架实现方式、适用场景和优缺点进行详细说明: 1. 授权模型类型与定义 模型名称定义特点RBAC(基于角色的访问控制)通…...
aws平台练习
注册 AWS 账户 访问 AWS 官方网站,点击“免费注册”按钮,按照提示完成账户注册: 提供电子邮件地址、密码和电话号码。 验证身份(可能需要手机验证码)。 设置 billing 信息。 2. 登录 AWS 管理控制台 使用注册的邮箱和…...
力扣DAY40-45 | 热100 | 二叉树:直径、层次遍历、有序数组->二叉搜索树、验证二叉搜索树、二叉搜索树中第K小的元素、右视图
前言 简单、中等 √ 好久没更了,感觉二叉树来回就那些。有点变懒要警醒,不能止步于笨方法!! 二叉树的直径 我的题解 遍历每个节点,左节点最大深度右节点最大深度当前节点当前节点为中心的直径。如果左节点深度更大…...
【MYSQL从入门到精通】数据类型及建表
一些基础操作语句 1.使用客户端工具连接数据库服务器:mysql -uroot -p 2.查看所有数据库:show databases; 3.创建属于自己的数据库: create database 数据库名;create database if not exists 数据库名; 强烈建议大家在建立数据库时指定编…...
【动态规划】 深入动态规划—两个数组的dp问题
文章目录 前言例题一、最长公共子序列二、不相交的线三、不同的子序列四、通配符匹配五、交错字符串六、两个字符串的最小ASCII删除和七、最长重复子数组 结语 前言 问题本质 它主要围绕着给定的两个数组展开,旨在通过对这两个数组元素间关系的分析,找出…...
结合大语言模型整理叙述并生成思维导图的思路
楔子 我比较喜欢长篇大论。这在代理律师界被视为一种禁忌。 我高中一年级的时候因为入学成绩好(所在县榜眼名次),直接被所在班的班主任任命为班长。我其实不喜欢这个岗位。因为老师一来就要提前注意到,要及时喊“起立”、英语课…...
Kotlin学习
kotlin android 开源,Kotlin开源项目集合_晚安 呼-华为开发者空间 干货来袭,推荐几款开源的Kotlin的Android项目 https://zhuanlan.zhihu.com/p/536789267 【已解决】 ubuntu apt-get update连不上dl.google.com_为什么不能ping谷歌-CSDN博客...
若依前后端分离版本从mysql切换到postgresql数据库
一、修改依赖: 修改admin模块pom.xml中的依赖,屏蔽或删除mysql依赖,增加postgresql依赖。 <!-- Mysql驱动包 --> <!--<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId> &l…...
【力扣hot100题】(073)数组中的第K个最大元素
花了两天时间搞明白答案的快速排序和堆排序。 两种都写了一遍,感觉堆排序更简单很多。 两种都记录一下,包括具体方法和易错点。 快速排序 class Solution { public:vector<int> nums;int quicksort(int left,int right,int k){if(leftright) r…...
【AAOS】【源码分析】CarAudioService(二)-- 功能介绍
汽车音频是 Android 汽车操作系统 (AAOS) 的一项功能,允许车辆播放信息娱乐声音,例如媒体、导航和通信。AAOS 不负责具有严格可用性和时间要求的铃声和警告,因为这些声音通常由车辆的硬件处理。将汽车音频服务集成在汽车中,彻底改变了驾驶体验,为驾驶员和乘客提供了音乐、…...
mapbox基础,加载F4Map二维地图
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性二、🍀F4Map 简介2.1 ☘️技术特点2.2 ☘️核…...
Android:Android Studio右侧Gradle没有assembleRelease等选项
旧版as是“Do not build Gradle task list during Gradle sync” 操作这个选项。 参考这篇文章:Android Studio Gradle中没有Task任务,没有Assemble任务,不能方便导出aar包_gradle 没有task-CSDN博客 在as2024版本中,打开Setting…...
DRAM CRC:让DDR5内存数据更靠谱
DRAM(动态随机存取存储器)是电脑内存的核心部件,负责存储和传输数据。如果数据在传输中出错,后果可能很严重,比如程序崩溃或者数据损坏。为了解决这个问题,DDR5内存引入了一个新功能,叫DRAM CRC(循环冗余校验)。简单来说,它是用来检查读写数据有没有问题的工具。 下面…...
RAI Toolbox详解
RAI Toolbox详解 摘要 RAI Toolbox是一个综合性的工具集,旨在帮助开发者和AI系统利益相关者更负责任地开发和监控AI系统,并做出更好的数据驱动决策。本文将详细介绍RAI Toolbox的功能、使用场景以及与类似AI项目的对比,帮助读者全面了解RAI…...
心率测量-arduino+matlab
参考:【教程】教你玩转Stduino之手指心跳检测模块 - 知乎 (zhihu.com) 1 原理 心跳检测模块,由一个红外线发射LED和红外接收器构成。手指心跳监测模块能够测量脉搏,是这样工作的:当手指放在发射器与接收器之间,红外发射…...
H3C的MSTP+VRRP高可靠性组网技术(MSTP单域)
以下内容纯为博主分享自己的想法和理解,如有错误轻喷 MSTP多生成树协议可以基于不同实例实现不同VLAN之间的负载分担 VRRP虚拟路由器冗余协议可以提高网关的可靠性防止单点故障的可能 在以前这两种协议通常一起搭配组网,来提高网络的可靠性和稳定性&a…...
字符串替换 (模拟)神奇数 (数学)DNA序列 (固定长度的滑动窗口)
⭐️个人主页:小羊 ⭐️所属专栏:每日两三题 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 字符串替换 (模拟)神奇数 (数学)DNA序列 (固定长度的滑动窗口&am…...
Centos7下安装hive详细步骤
在Centos 7系统上安装Hive的步骤如下: 下载Hive:首先,在Apache Hive的官方网站上下载最新版本的Hive压缩包,地址为:https://hive.apache.org/downloads.html。选择合适的版本并下载。 解压Hive压缩包:将下…...
Verilog学习-1.模块的结构
module aoi(a,b,c,d,f);/*模块名为aoi,端口列表a、b、c、d、f*/ input a,b,c,d;/*模块的输入端口为a,b,c,d*/ output f;;/*模块的输出端口为f*/ wire a,b,c,d,f;/*定义信号的数据类型*/ assign f~((a&b)|(~(c&d)));/*逻辑功能描述*/ endmoduleveirlog hdl 程…...
