网络编程(24)——实现带参数的http-get请求
文章目录
- 二十四、day24
- 1. char 转为16进制
- 2. 16进制转为 char
- 3. URL 编码函数
- 4. URL 解码函数
- 5. 实现 get 请求参数的解析
- 6. 测试
二十四、day24
我们在前文通过beast实现了http服务器的简单搭建,但是有很多问题我们并没有解决。
在前文中,我们的 get 请求不带任何参数,那如果我们想要实现带参数的 get 请求,我们应该如何做?首先应考虑实现 url 的解析函数,解析 get 请求携带的参数。
1. char 转为16进制
unsigned char ToHex(unsigned char x) {return x > 9 ? x + 55 : x + 48;
}
该函数用于将 4 位无符号整数(取值范围为 0 到 15)转换为十六进制字符(0到9 和 A到F),超过这个范围的值不属于十六进制的规范。
- 如果
x > 9,说明它是 10 到 15 之间的值,对应十六进制的A到F。此时,x + 55将其转换为对应的 ASCII 字符。 - 如果
x <= 9,说明它是 0 到 9 之间的值,对应十六进制的0到9。此时,x + 48将其转换为对应的 ASCII 字符。
举例:
int main() {for (int i = 0; i <= 15; ++i) {std::cout << "ToHex(" << i << ") = " << ToHex(i) << std::endl;}return 0;
}
输出:
ToHex(0) = 0
ToHex(1) = 1
ToHex(2) = 2
ToHex(3) = 3
ToHex(4) = 4
ToHex(5) = 5
ToHex(6) = 6
ToHex(7) = 7
ToHex(8) = 8
ToHex(9) = 9
ToHex(10) = A
ToHex(11) = B
ToHex(12) = C
ToHex(13) = D
ToHex(14) = E
ToHex(15) = F
2. 16进制转为 char
unsigned char FromHex(unsigned char x) {unsigned char y;if (x >= 'A' && x <= 'Z') y = x - 'A' + 10; // 处理大写字母else if (x >= 'a' && x <= 'z') y = x - 'a' + 10; // 处理小写字母else if (x >= '0' && x <= '9') y = x - '0'; // 处理数字else assert(0); // 如果输入非法,触发断言return y;
}
该函数用于将一个 十六进制字符 转换为其对应的 4 位无符号整数值,支持处理大写字母(A-Z)、小写字母(a-z)和数字(0-9)
3. URL 编码函数
至于为什么需要上面两个函数实现十六进制和十进制的互转,得益于下面这个函数。
std::string UrlEncode(const std::string& str) {std::string strTemp = "";size_t length = str.length();for (size_t i = 0; i < length; i++) {// 判断字符是否无需编码(字母、数字、安全字符)if (isalnum((unsigned char)str[i]) ||(str[i] == '-') || (str[i] == '_') || (str[i] == '.') || (str[i] == '~')) {strTemp += str[i];}// 处理空格(替换为 '+')else if (str[i] == ' ') {strTemp += "+";}// 其他字符进行百分比编码(%XX)else {strTemp += '%';strTemp += ToHex((unsigned char)str[i] >> 4); // 高 4 位strTemp += ToHex((unsigned char)str[i] & 0x0F); // 低 4 位}}return strTemp;
}
该函数对输入的字符串进行 URL 编码(也称为百分比编码),确保字符串可以在 URL 中安全传输。URL 编码会将特殊字符转换为 % 后跟两个十六进制字符的形式。
编码规则
- 无需编码的字符:
- 字母(
A-Z,a-z)、数字(0-9)。 - 安全字符:
-、_、.、~(根据 RFC 3986 标准)。
- 字母(
- 空格处理:
- 空格被替换为
+(符合application/x-www-form-urlencoded格式,常见于表单提交)。
- 空格被替换为
- 需要编码的字符:
- 其他所有字符(如
!、#、$、%、&、=等)会被转换为%后跟两个十六进制字符。 - 例如,字符
@的 ASCII 码是0x40,会被编码为%40。
- 其他所有字符(如
举例:
假设输入字符串为 "Hello World!@#",编码过程如下:
'H'、'e'、'l'、'l'、'o':无需编码。' '(空格):替换为+。'W'、'o'、'r'、'l'、'd':无需编码。'!':ASCII 码为0x21,编码为%21。'@':ASCII 码为0x40,编码为%40。'#':ASCII 码为0x23,编码为%23。
最终编码结果:
"Hello+World%21%40%23"
百分比编码:
- 使用
ToHex函数将字符的高 4 位和低 4 位转换为十六进制字符。 - 例如,字符
'#'(ASCII 码0x23)的转换:- 高 4 位:
0x2→'2'(ToHex(0x2) = '2')。 - 低 4 位:
0x3→'3'(ToHex(0x3) = '3')。 - 结果:
%23。
- 高 4 位:
- 同理,汉字的编码过程同样如此
严格遵循 URL 编码标准(RFC 3986)时,空格应编码为
%20,而非+。+是application/x-www-form-urlencoded的约定。若需兼容 RFC 3986,可将str[i] == ' '分支改为strTemp += "%20"
4. URL 解码函数
std::string UrlDecode(const std::string& str)
{std::string strTemp = "";size_t length = str.length();for (size_t i = 0; i < length; i++){//还原+为空if (str[i] == '+') strTemp += ' ';//遇到%将后面的两个字符从16进制转为char再拼接else if (str[i] == '%'){assert(i + 2 < length);unsigned char high = FromHex((unsigned char)str[++i]);unsigned char low = FromHex((unsigned char)str[++i]);// 将高 4 位和低 4 位组合成一个字节,即将一个十六进制字符转化为十进制strTemp += high * 16 + low;}else strTemp += str[i];}return strTemp;
}
该函数对 URL 编码的字符串进行解码,将其还原为原始字符串。
5. 实现 get 请求参数的解析
参考网络编程(21)——通过beast库快速实现http服务器 | 爱吃土豆的个人博客,我们在 HttpConnection 类中新添加两个私有成员:
std::string _get_url;
std::unordered_map<std::string, std::string> _get_params;
因为 URL 中 GET 请求的参数是通过查询字符串表示的,查询字符串附加在 URL 的末尾,用于向服务器传递键值对形式的参数,格式如下:
?key1=value1&key2=value2&key3=value3
?:表示查询字符串的开始。key=value:参数以键值对的形式表示。&:用于分隔多个键值对。
举例:
假设有一个 URL:
https://www.example.com/search?q=hello+world&lang=en%2Fus&page=2
- 查询字符串:
?q=hello+world&lang=en%2Fus&page=2 - 参数:
q=hello worldlang=en/uspage=2
并定义函数 PreParseGetParam用于对查询字符串进行编解码:
void HttpConnection::PreParseGetParam() {// 提取 URI http://localhost:1250/get_test?key1=value1&key2=value2auto uri = _request.target();// 查找查询字符串的开始位置(即 '?' 的位置) auto query_pos = uri.find('?');if (query_pos == std::string::npos) {_get_url = uri;return;}// 获取 URI 的路径部分(? 前的部分)_get_url = uri.substr(0, query_pos);// 获取查询字符串(? 后的部分)std::string query_string = uri.substr(query_pos + 1);std::string key;std::string value;size_t pos = 0; // 循环中找到每个 & 分隔符的位置while ((pos = query_string.find('&')) != std::string::npos) {auto pair = query_string.substr(0, pos);size_t eq_pos = pair.find('=');if (eq_pos != std::string::npos) {key = UrlDecode(pair.substr(0, eq_pos)); // 假设有 url_decode 函数来处理URL解码 value = UrlDecode(pair.substr(eq_pos + 1));_get_params[key] = value;}query_string.erase(0, pos + 1);}// 处理最后一个参数对(如果没有 & 分隔符) if (!query_string.empty()) {size_t eq_pos = query_string.find('=');if (eq_pos != std::string::npos) {key = UrlDecode(query_string.substr(0, eq_pos));value = UrlDecode(query_string.substr(eq_pos + 1));_get_params[key] = value;}}
}
然后在函数 process_request 中的 get 部分添加:
void process_request() {
//................case http::verb::get:PreParseGetParam();
//................
}
然后在 create_response 函数中添加如下代码:
void create_response() {
//................else {_response.result(http::status::not_found);_response.set(http::field::content_type, "text/plain");beast::ostream(_response.body()) << "File not found\r\n";}int i = 0;for (auto& elem : _get_params) {i++;beast::ostream(connection->_response.body()) << "param " << i << "key is " << elem.first;beast::ostream(connection->_response.body()) << "param " << i << "value is " << elem.second << std::endl;}
}
用于显示获取的参数.
6. 测试
浏览器地址栏中输入:localhost:1250/get_test?key1=value1&key2=value2
浏览器显示如下结果:

不带参数的结果为:

相关文章:
网络编程(24)——实现带参数的http-get请求
文章目录 二十四、day241. char 转为16进制2. 16进制转为 char3. URL 编码函数4. URL 解码函数5. 实现 get 请求参数的解析6. 测试 二十四、day24 我们在前文通过beast实现了http服务器的简单搭建,但是有很多问题我们并没有解决。 在前文中,我们的 get…...
东方财富股吧发帖与评论爬虫
东方财富股吧发帖与评论爬虫 东方财富股吧爬虫 写在开头项目介绍主要功能文件介绍爬取逻辑 a. 爬取帖子信息b. 爬取评论信息 使用步骤 1. 下载代码2. MongoDB 安装3. Webdriver 安装4. 运行 main.py5. 查看数据 踩过的坑附录(运行结果) 东方财富股吧爬…...
【Elasticsearch】match_bool_prefix查询
match_bool_prefix查询是 Elasticsearch 中一种用于全文搜索的查询方式,适用于需要同时匹配多个词汇,但词汇顺序不固定的情况,它结合了布尔查询(bool)和前缀查询(prefix)的功能,适用…...
微信小程序image组件mode属性详解
今天学习微信小程序开发的image组件,mode属性的属性值不少,一开始有点整不明白。后来从网上下载了一张图片,把每个属性都试验了一番,总算明白了。现总结归纳如下: 1.使用scaleToFill。这是mode的默认值,sc…...
数据结构:最小生成树
1.基本概念 生成树:连通无向图的生成树是包含图中所有顶点的极小连通子图(无环)。 最小生成树:所有生成树中边权重总和最小的那棵。 2.常用算法 克鲁斯卡尔算法(Kruskal) 步骤: 将所有边按权…...
C语言-章节 4:函数的定义与声明 ——「神秘法术的卷轴」
少年和 Inta 成功通过运算符与表达式的考验后,继续在函数城堡中探索。他们沿着一条闪烁着幽光的走廊前行,走廊两侧的墙壁上刻满了奇异的符号,仿佛在诉说着古老的编程秘密。终于,他们来到了一间神秘的房间,房间中央悬浮…...
《云原生安全攻防》-- K8s镜像安全:镜像全生命周期安全管理
从攻击者的角度来看,针对容器镜像的软件供应链攻击和镜像投毒等攻击方式,不仅攻击成本低,而且还能带来更高且持久的收益。因此,镜像安全问题变得日益突出。 在本节课程中,我们将深入探讨镜像全生命周期的安全管理&…...
uniapp商城之首页模块
文章目录 前言一、自定义导航栏1.静态结构2.修改页面配置3.组件安全区适配二、通用轮播组件1. 静态结构组件2.自动导入全局组件3.首页轮播图数据获取三、首页分类1.静态结构2.首页获取分类数据并渲染四、热门推荐1.静态结构2.首页获取推荐数据并渲染3.首页跳转详细推荐页五、猜…...
【Javascript Day13、14、15、16】
html的DOM操作 // JS 是为了让页面实现动态网页效果 // 动态和静态区分取决于JS的和页面标签的数据交互 // 动态网页:有数据交互 // 静态网页:无数据交互 // JS 和 元素的关联操作对象 DOM // 整个HT…...
linux 板子的wifi模块连上路由器后,用udhcpc给板子wifi分配ip,udhcpc获取到ip,但没有写入wlan0网卡上
linux 板子的wifi模块连上路由器后,用udhcpc给板子wifi分配ip,udhcpc获取到ip,但没有写入wlan0网卡上 这里的问题是 /usr/share/udhcpc/default.script脚本有问题 用下面正确脚本,即可写进去 #!/bin/sh# udhcpc script for busybox # Copyr…...
openGauss 3.0 数据库在线实训课程13: 学习逻辑结构:表管理1
前提 我正在参加21天养成好习惯| 第二届openGauss每日一练活动 课程详见:openGauss 3.0.0数据库在线实训课程 学习目标 学习openGauss表的创建、搜索路径和访问方法等 课程作业 1.创建一个表(默认,不指定模式),查…...
网络编程-
文章目录 网络编程套接字UDP/TCP的api使用 网络编程套接字 socket,是操作系统给应用程序(传输层给应用层)提供的api,Java也对这个api进行了封装。 socket提供了两组不同的api,UDP有一套,TCP有一套&#x…...
基于单片机的常规肺活量SVC简单计算
常规肺活量 SVC(Slow Vital Capacity)是指尽力吸气后缓慢而又完全呼出的最大气量。 成年男性的肺活量通常在 3500-4000ml 之间,成年女性的肺活量通常在 2500-3000ml 之间。 单片机一般通过外接流量传感器,使用ADC高速采集的方式…...
【PostgreSQL】PG在windows下的安装
一、准备 通过官网下载安装文件,官方下载路径如下: https://www.postgresql.org/download/windows/ 二、安装 双击postgresql-17.3-1-windows-x64.exe文件,启动安装,进入安装步骤,点击Next 选择PG安装路径ÿ…...
电动汽车电池监测平台系统设计(论文+源码+图纸)
1总体设计 本次基于单片机的电池监测平台系统设计,其整个系统架构如图2.1所示,其采用STC89C52单片机作为控制器,结合ACS712电流传感器、TLC1543模数转换器、LCD液晶、DS18B20温度传感器构成整个系统,在功能上可以实现电压、电流、…...
基于和声搜索(Harmony Search, HS)的多中心点选址优化算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于和声搜索(Harmony Search, HS)的多中心点选址优化算法matlab仿真。可以设置多个不同的中心点。 2.测试软件版本以及运行结果展示 matlab2022a/matlab2024b版…...
单链表的概念,结构和优缺点
1. 概念 链表是一种物理存储结构上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 2. 单链表的结构 单链表是由一系列节点组成的线性结构,每个结点包含两个域。:数据域和指针域。 数据域用来…...
SpringBoot+数据可视化的奶茶点单购物平台(程序+论文+讲解+安装+调试+售后)
感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,我会一一回复,希望帮助更多的人。 系统介绍 本奶茶点单购物平台搭建在 Spring Boot 框架之上,充分利用其强大的依赖管理机…...
深入理解 Vue3 中 ref 与 reactive 的区别及应用
深入理解 Vue3 中 ref 与 reactive 的区别及应用 在 Vue3 的开发世界里,响应式编程是其核心特性之一,而ref与reactive作为实现响应式的关键 API,理解它们的区别和适用场景对于开发者来说至关重要。本文将带你深入剖析这两个 API,…...
TDengine 客户端连接工具 taos-Cli
简介工具获取运行命令行参数 基础参数高级参数 数据导出/导入 数据导出数据导入 执行 SQL 脚本使用小技巧 TAB 键自动补全设置字符列显示宽度其它 错误代码表 简介 TDengine 命令行工具(以下简称 TDengine CLI)是用户操作 TDengine 实例并与之交互最简…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...
规则与人性的天平——由高考迟到事件引发的思考
当那位身着校服的考生在考场关闭1分钟后狂奔而至,他涨红的脸上写满绝望。铁门内秒针划过的弧度,成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定",构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...
