@bit::Shadow
✧(≖ ◡ ≖✿
目录
🔗html及图片显示gitee
浏览器作为客户端,我的代码作为服务端。
链接过程如下
bash
我的浏览器(Win)
|发送HTTP请求到 122.152.208.179:8080(公网IP+服务端开放端口号)
|
互联网路由
|路由转发
云服务商网络
|防火墙允许8080端口
云服务器(122.152.208.179)
|操作系统将数据交给监听8080的进程
|
你的serverTCP程序
|解析HTTP请求
返回HTTP响应
|原路返回
浏览器显示内容
抓取浏览器的HTTP格式的请求
cpp
GET /favicon.ico HTTP/1.1
Host: 122.152.208.179:8080
Connection: keep-alive
User-Agent: Mozilla/5.0 (Linux; Android 15; Pixel 9) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Mobile Safari/537.36
Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
Referer: http://122.152.208.179:8080/wwwroot/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
[空行]
[正文](选择性)
请求格式必然满足下图(本质是字符数组)
请求行格式
注意请求行格式顺序:
请求方法-空格-URI-空格-HTTP版本-换行符

将请求内容通过read()读取后输出
cpp
void Start(std::unique_ptr<SocketClass>& clientfd)
{
_clfd = clientfd->sockfdGet ();
// 回显浏览器请求至于显示器
char buf[8096] = { 0 };
int n = read (_clfd, buf, 8095);
if(n > 0)
{
//也可能读不全!!!尝试直接输出
LOG (LogLevel::DEBUG)
<< "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&";
std::cout << buf;
LOG (LogLevel::DEBUG)
<< "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&";
}
else if(n == 0)
{
LOG (LogLevel::INFO) << "客户端已退出";
exit (0);
}
else
RETFATAL ("read");
}
得到
bash
GET / HTTP/1.1
Host: 122.152.208.179:8082
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
ubuntu@VM-0-11-ubuntu:~/e2026/Ubuntu_learning/Auguest/HTTP$
表示:
"我是Chrome浏览器用户,使用Windows 10系统,想要访问
http://122.152.208.179:8082/,我接受HTML页面和中文内容,如果支持压缩更好。如果服务器支持HTTPS升级,我也可以接受。"
请求行
bash
GET / HTTP/1.1
GET:请求方法表示客户端希望获取资源。
/ : 请求的URI(统一资源标识符),"表示根路径"。
HTTP/1.1:使用的HTTP版本。
请求头
bash
Host: 122.152.208.179:8082
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
| 字段 | 值 | 含义 |
|---|---|---|
| Host | 122.152.208.179:8082 |
必填。指定目标服务器地址和端口,支持虚拟主机 |
| Connection | keep-alive |
保持TCP连接复用,避免每次请求重新建立连接 |
| Upgrade-Insecure-Requests | 1 |
告诉服务器客户端支持升级到HTTPS(如果服务器支持) |
| User-Agent | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36... |
客户端标识:Windows 10系统,Chrome 151版本,基于WebKit内核 |
| Accept | text/html,application/xhtml+xml,application/xml;q=0.9,... |
告诉服务器客户端可接受的响应内容类型,按优先级排序(q值表示权重,q=0.9优先) |
| Accept-Encoding | gzip, deflate |
客户端支持的压缩算法,服务器可用这些算法压缩响应体 |
| Accept-Language | zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7 |
客户端偏好的语言:中文优先,英文其次 |
空行
bash
[空行]
请求头之后必定有一个空行,表示请求头结束。之后若存在请求体(正文)(如POST表单的请求数据),则放在空行之后。(由于此处是GET方法,所以一定无正文)
正文
请求方(Request)
| 情况 | 是否有正文 | 说明 | 示例 |
|---|---|---|---|
| GET | ❌ | 获取资源 | 访问网页 |
| POST | ✅ | 传输实体 | 提交表单、上传文件 |
| HEAD | ❌ | 获得报文首部 | 只获取响应头 |
| DELETE | ❌ | 删除文件 | 删除资源 |
| PUT | ✅ | 传输文件 | 更新资源 |
| PATCH | ✅ | 部分更新 |
70%为GET20%为POST10%为其他。
POST举例Login.html
POST常用于像服务端提交数据:提交表单、文件上传、API调用等。
见资源绑定(测试)
效果图演示:

当我们输入登录信息(即传输数据)浏览器请求如下
cpp
POST /login HTTP/1.1
Host: 122.152.208.179:8085
Content-Type: application/x-www-form-urlencoded
Content-Length: 43
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.9
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
username=Salad&password=2024019&remember=no
最后一行即请求正文:
cpp
username=Salad&password=2024019&remember=no
即请求正文(未加密,因为使用的是http)
在html内即

注意:GET与POST均不安全均可以被抓包获取,因此常使用https来加密处理。
服务端应答
基本应答内容块

状态行:
HTTP版本-空格-状态码-空格-状态码描述-换行符

响应报头
描述客户端、服务端、响应正文、甚至时间等等信息。
响应正文(最重要、最核心)
是传输到客户端(浏览器),供给解析的内容。
因此为兼容多种格式像:html、cs、js等我们使用二进制读取的方法。
cpp
#include<fstream>
bool ReadFile1(const std::string filename, std::string& out)
{
std::ifstream file(filename, std::ios::in | std::ios::binary);
if (!file.is_open())
{
return false;
}
out.clear();
std::ostringstream buffer;
buffer << file.rdbuf();
if (file.fail() && !file.eof())
{
return false;
}
out = buffer.str();
return true;
}
在四大模块中无疑正文是最重要的部分,它决定了响应什么。其次就是状态行的解释,供浏览器识别版本协议等信息。(自然最本质的底层信息的发送是基于网络的TCP/UDP协议实现的,ta提供send与accept等接口联系了服务端与客户端)
本质
由此可见http不过在TCP/UDP之上的封装而已,而 js css html则称为"解释性语言"、"应用层开发语言",而C/C++本质是"底层开发"。
最基本的浏览器响应
浏览器的响应解析必须是基于上图的特定格式,因此有以下最简单格式
cpp
// 最基本的 HTTP 响应
const char* minimalResponse =
"HTTP/1.1 200 OK\r\n"
"\r\n"
"Hello World!";
即:响应行+空行+正文
浏览器的强大解析能力了解
由于浏览器的强大解析能力我们甚至在响应行可以删除部分元素:
状态行甚至可以变成这个样子,都可以正常解析。
cpp
HTTP/1 0 O
感谢支持,长期连载
欢迎关注
