网络编程(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 实例并与之交互最简…...
深蓝词库转换:彻底告别输入法切换烦恼的终极解决方案
深蓝词库转换:彻底告别输入法切换烦恼的终极解决方案 【免费下载链接】imewlconverter ”深蓝词库转换“ 一款开源免费的输入法词库转换程序 项目地址: https://gitcode.com/gh_mirrors/im/imewlconverter 你是否曾经因为更换输入法而不得不放弃多年积累的个…...
面试官最爱问的图遍历:BFS在LeetCode「岛屿数量」和「打开转盘锁」中的实战拆解
面试官最爱问的图遍历:BFS在LeetCode「岛屿数量」和「打开转盘锁」中的实战拆解 最近在技术面试中,图的广度优先搜索(BFS)算法成为了高频考点。不同于教科书式的理论讲解,本文将聚焦LeetCode上两道经典题目——200.岛屿…...
Node.js 服务端应用快速接入 Taotoken 实现智能客服回复功能
Node.js 服务端应用快速接入 Taotoken 实现智能客服回复功能 1. 准备工作 在开始编码前,需要完成两项基础配置:获取 Taotoken API Key 并安装必要的 Node.js 依赖。登录 Taotoken 控制台,在「API 密钥」页面创建新密钥,建议为生…...
PCB/PCBA板厚测试用什么设备好?
关于板厚测试,国内测量仪器、智能检测设备专业解决方案供应商——Bamtone班通有一款非常出色的产品——BAMTONE/L750A自动板厚测试机。核心用途在于PCB制造过程中实现高精度的板厚自动检测与监控,这款设备在PCB/PCBA、汽车、机加工等行业有着广泛的应用&…...
【无人机三维路径规划】基于星雀算法NOA实现复杂城市地形下无人机航路规划附matlab代码
✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,代码获取、论文复现及科研仿真合作可私信。 🍎个人主页:Matlab科研工作室 🍊个人信条:格物致知。 🔥 内容介绍 一、 引…...
灵机一物AI原生电商小程序、PC端(已上线)-【2026 硅谷职场剧变】AI-first 重构产品岗:大厂裁 3 万招 8 千,Builder取代传统 PM
1. 背景:硅谷开启 “先裁后招” 周期2026 年 AI 全面渗透,科技公司人力结构迎来清算时刻。行业共识:未来 12-24 个月,大厂将批量裁员,再定向招募 AI 原生人才。典型模式:裁 3 万传统岗位,召回 8…...
从“水仙花数”到“背包问题”:新手程序员如何用C语言打通算法任督二脉?
从“水仙花数”到“背包问题”:新手程序员如何用C语言打通算法任督二脉? 第一次接触算法时,我盯着屏幕上那行"Hello World"发呆——明明已经能写出让计算机打招呼的代码,为什么看到"时间复杂度O(n)"这种描述时…...
C++模板技术(泛型编程)
template<typename T> T sum(T a,T b){return ab; }以上称呼为函数模板,调用时生成模板函数template<typename T> int sum(T a, T b) {return a b; } template<> int sum(int * a,int* b) {return *a*b; }int main(int agvn, char* agvc[]) {in…...
小米手机+AutoX.js 28.1.0极速版:保姆级自动化测试环境搭建与脚本调试指南
小米手机AutoX.js 28.1.0极速版:保姆级自动化测试环境搭建与脚本调试指南 在移动应用开发与测试领域,自动化测试已成为提升效率的关键手段。AutoX.js作为基于JavaScript的安卓自动化工具,凭借其轻量级和易用性,成为众多开发者的首…...
OpenUI Lang:专为AI流式生成UI设计的高效语言与框架实践
1. 项目概述:OpenUI,一个为生成式UI而生的新标准如果你和我一样,在过去一年里尝试过用大语言模型(LLM)来生成用户界面,那你一定经历过这种痛苦:模型吐出一大段JSON,你得写个复杂的解…...
