
HTTP协议,以及它的请求与答复信息的格式(请求行,请求包头,正文等),对一些比较重要的部分来展开讲解,其他不常用的即一概而过,从静态网页到动态网页的过渡,最后底层基于TCP实现简单的HTTP服务器的代码编写构建一个简单的网页(包含对应的跳转,重定向,动态交互等功能),采取边讲解http结构边用代码形成效果展示的形式进行讲解,望有助!

欢迎拜访: 点击进入博主主页 本篇主题: 探秘HTTP应用层那些事儿! 制作日期: 2025.07.21 隶属专栏: 点击进入所属Linux专栏
本文将要介绍的内容的大致流程图如下:
HTTP超文本传输协议) 是一个至关重要的协议。 它定义了客户端(如浏览器) 与服务器之间如何通信, 以交换或传输超文本(如 HTML 文档) 。
HTTP 协议向服务器发送请求, 服务器收到请求后处理并返回响应。 HTTP 协议是一个无连接、 无状态的协议, 即每次请求都需要建立新的连接, 且服务器不会保存客户端的状态信息(后面我们详细讲解)。
我们要明白:
远端拿数据,要么上传数据到远端(数据:短视频,视频,网页,图片,音频)。本质:
某个文件等(底层走的还是TCP那套逻辑)。URL网址!下面就拿我的博客的URL为例说明:
https://blog.csdn.net/2401_82648291?spm=1010.2135.3001.5343详细解释如图:

解释:我们输入网址进行访问(http协议)就是拿着指定ip+port连接到具体主机的具进程(类似我们之前写的服务器)﹔然后浏览器把路径按照规定进行编码(特殊字符)然后这个符合要求的uri(路径)发送给指定进程;再由这个进程执行完(找到对应内容或者进行对应方法执行)把结果返回来!陪一张标准的介绍:

urlencode与urldecode有些字符不能随意出现.比如, 某个参数中需要带有这些特殊字符(/ 或者?), 就必须先对特殊字符进行转义。
16 进制, 然后从右到左, 取 4 位(不足 4 位直接处理), 每 2 位做一位, 前面加上%, 编码成%XY 格式。
比如:

HTTP 协议请求与响应格式下面简单认识下http结构:

不依赖任何第三方库。下面形象看一下:

不是所有的http请求,都会携带数据)。
把它看做一个长的字符串!
请求以及回复先放图:

原理解释:
ip+port就可以找到对应的服务器端进程了;接着把后面跟的具体路径(uri)内容(也可以空)等进行填充请求报头;是get还是post(请求方法);然后按照上面的request的格式打包之后成一个长的字符串;然后发送给服务端;服务端就要进行解析;根据uri具体位置把内容拿出来放到自己的响应正文里(html);最后序列化发回去;剩下就是浏览器提取进行先关转化!!!序列化和反序列化解析request
浏览器构建。哈希表的K-V结构储存。如何进行解析出来:
\r\n(第一个)来成功提取请求行,把请求方法/版本/uri解析出来(第一个都找不到就是无效的http请求了)。空行,然后找到对应的Content-Length的长度,对应读取下一行(千万不要再继续按照上面要求读取因为最后一行无\r\n)构建response
响应正文。长字符串。剩下的就交给浏览器自己转义即可!
request与response的组成部分请求方法:
这里我们主要介绍的是POST和GET方法,代码演示也是用他俩。
GET代码书写也是先以get为例,简单来说就是获取对应资源!
POST当然了,还有PUT(推送数据到服务端) HEAD(只返回相应头) DELETE (删除服务端数据)OPTIONS(查询URL指定资源)等,这些不常用,这里就不讲解了。
陪一张图:

下面我们利用图片通俗易懂来认识下:

输入对应的web根目录(/)

这个路径就是uri,然后服务端就会对应位置找到资源,返回给我们:

'/ '不是Linux 根目录,是Linux服务器的一个web目录(wwwroot),资源都放在这个目录下(如果路径不是/,服务器自动拼接首页)。因此:
首页作为站点的入口,一个网站就是一颗多叉树,点击链接的时候,浏览器会形成新的访问地址,发起二次请求。下面我们来验证下:


然后比如点击了主页:

总结下:
HTTP版本微信低版本的客户端;然后给服务端发起请求:服务端识别到你的http的版本是低的就提供给你低版本服务(这里对于一些app应用也可以理解成是被限制的浏览器,其实也是发送http的网页请求)。
认识状态码描述HTTP状态码:

详细版:
状态码 | 英文名称 | 含义解释 |
|---|---|---|
200 | OK | 请求成功,服务器返回对应数据 |
201 | Created | 请求成功且创建了新资源 |
204 | No Content | 请求成功,但无内容返回 |
301 | Moved Permanently | 资源永久重定向到新地址 |
302 | Found | 资源临时重定向到新地址 |
304 | Not Modified | 资源未修改,可直接使用缓存 |
400 | Bad Request | 客户端请求语法错误 |
401 | Unauthorized | 请求需要身份认证,未授权 |
403 | Forbidden | 服务器拒绝请求,无访问权限 |
404 | Not Found | 服务器找不到请求的资源 |
500 | Internal Server Error | 服务器内部错误,处理请求失败 |
502 | Bad Gateway | 网关错误,代理服务器获取响应失败 |
503 | Service Unavailable | 服务器暂时不可用,可能因维护或过载 |
200(OK),404(NotFound),403(Forbidden),302(Redirect重定向), 504(Bad Gateway),我们暂时只需要了解这些即可。认识HTTP 常见 Header首先我们先认识下客户端收到答复是如何解析的:

如何提取相应正文:
陪一张header表:
字段名 | 含义 |
|---|---|
Content-Type | 数据类型(如 text/html 等) |
Content-Length | Body 的长度(单位为比特) |
Host | 客户端告知服务器,所请求的资源是在哪个主机的哪个端口上 |
User-Agent | 声明用户的操作系统和浏览器版本信息 |
referer | 当前页面是从哪个页面跳转过来的 |
Location | 搭配 3xx 状态码使用,告诉客户端接下来要去哪里访问 |
Cookie | 用于在客户端存储少量信息,通常用于实现会话(session)的功能 |
下面我们就先来认识Content-Length,Content-type,Connection这几个报头为主来讲解:
据类型(text/html等)对应的后缀比如png mp4等都对应的有不同类型(这里我们直接截取后缀进行判断添加即可)。1·c++文件操作/2·系统自带的stat函数。那么下面我们根据这俩个报头给我们之前写的http答复添加上:
大致思路:
注意:
// 读取对应路径下的html:
static bool readfile(std::string &text, std::string tar)
{ // 1·文本读取(比如读取图片等可能会遇到\n等符号导致读取中断直接换行等当前行后面内容就无法读到,导致错误):
// std::ifstream in(tar.c_str());
// if (!in.is_open())
// return false;
// std::string line;
// while (std::getline(in, line))
// { // 使用getline读取的时候每次会将line情况在读取
// text += line;
// }
// in.close();
// return true;
// 2·二进制读取:
std::ifstream in(tar.c_str());
if (!in.is_open())
return false;
int size=filesize(tar);
text.resize(size);
in.read((char*)text.c_str(),size);//这里string不能强转char*因此可先调用c_str
return true;
} static int filesize(string file)
{ //c++文件io方法:
// ifstream in(file);
// if (!in.is_open())
// return 0;
// in.seekg(0, in.end);
// int size = in.tellg();
// in.seekg(0, in.beg);
// in.close();
// return size;
//系统调用:
struct stat buff;
int s = stat(file.c_str(), &buff);
return buff.st_size;
}有个非常阴险的bug:就是每次浏览器开一个新页面就会先向对应的服务端请求(/favicon.ico 一个文件)里面是那个小图标。

我们必须对它进行忽略处理:

比如我么我们第一次连接到主页的时候:

此外还建议,读取的时候数组开大一点(因为这里我们是默认它可以把请求都读上来的,忽略了其他情况)

解释下原理:
浏览器会请求这个图标也就是会也就是
Accept请求头会有对应的关于/favicon.ico对应的类型;然后如果我们还是上面的逻辑找不到就404的话(之前就可以,但是现在我们报头会返回类型这样就导致类型不匹配了,因此会出现问题)那么请求如果是它,此时我们在答复的时候就必须返回对应的类型的响应正文以及对应的Content-type是image/x-icon这个类型,否则浏览器就会爆出类型不匹配从而出错,因此问题就在于这个请求头的Accept与答复的Content-type及响应正文之间的不匹配问题,故对于这个图标的请求我们采取忽略不处理,“不理这个请求图标的进程了!”
因此:
直接忽略即可(这里浏览器多个请求访问其实是多个多个不同进程去访问的,也就是ip同port不同,因此服务端直接对发它的进程忽略不回复;接着对其他进程的请求再做答复即可)。根据此处小结一下:
下面我们根据我们制作的基于http的小网站的请求验证一下:

控制和管理客户端与服务器之间的连接状态。
HTTP/1.1:在 HTTP/1.1协议中,默认使用持久连接。当客户端和服务器都不明确指定关闭连接时,连接将保持打开状态,以便后续的请求和响应可以复用同一个连接。
HTTP/1.0:在 HTTP/1.0 协议中,默认连接是非持久的。如果希望在HTTP/1.0上实现持久连接,需要在请求头中显式设置Connection:keep-alive。
Connection:keep-alive:表示希望保持连接以复用TCP 连接,Connection:close:表示请求/响应完成后,应该关闭TCP 连接。
这里就涉及到长短连接了:
connect和accept一次,客户端和服务端就直接收发消息即可。


下面我们举些例子来看一下:
我们自己写的http服务器它就是短连接。
请求:


可以看到每次都要重新连接,故最后还是短连接!


总结下:
发送请求的时候,前提是客户端(浏览器)要支持长连接,然后发送1.1,告诉服务端要进行长连接,
最后协商后才是长连接,否则就默认短连接了(这里注意互相支持的协议应该相同)。
访问与应答原理分析:


video页面

不过,目前我们访问的资源全是以静态资源形式呈现的(文件)。
小结一下:
给我们之前的http服务器简单添加了两个报头分别是Content-type和Content-length;其次就是对于那个
小图标特判一下,接著裁是理解不同htm文件里的的转关系:其实就是浏优差再次选一个进程向同一个服务端访间;有的是直接在当前页面展现出来,有的就是直接刷新当前页面进行显示(比如a标签),还有的是跳转新页面进行展示–>归根结底,还是浏览器重新构建请求发送给服务器而已! ! !
telnet与wget指令telnet使用telent前提是安装后,把自己对应服务器的端口开放,防火墙关闭!
首先,我们需要知道:
进行安装telnet:
sudo apt install telnettelent ip port然后ctrl+]然后再回车即输入访问的网址或者请求即可,q为退出。
client界面 :

server界面:



wgetweb首页里对应文件内容+名称,下载到本地(爬虫)一些网站有反爬机制明确禁止。
sudo apt-get update
sudo apt-get install wget演示效果:下面我们抓取-下qq新闻页面:

进行爬取:
爬取结果:
重定向之永久重定向(301)+临时重定向(302)比如学校南门开了个超市,但是超市临时搬到了北门,因此就会在原来南门的位置搞个告示,这样学生们就看到了直接去北门了–>(
临时重定向)302+location!但是如果超市由于北门生意好,就搬到北门不回来了,因此它就会在原来南门的地方贴个告示说永久到北门–>(永久重定向)301+location!
client-server图形象理解下:
这里永久重定向主要是针对搜索引擎的,因为它要保证拿到对应公司网址的是最新的,因此需要记录下来之前被重定向的资源的新地址!!!
汉语搜索qq新闻,浏览器搜索引擎要能保证上面的这点,及时抓取对应的网址:
下面那我们实现的http网站演示下效果:
301 if (_route == "./wwwroot/redirect")
{
setcode(301); // 永久重定向:第一次被浏览器记录保存,剩下的再访问就直接到location目的网址访问
setheader("Location", "https://blog.csdn.net/2401_82648291?type=lately");
return true;
}301的永久重定向也是一样的,只不过这个浏览器不会记录,但是永久的会记录,到时候直接去那个地方即可(我们的属于短连接,每次请求完毕都会断开)效果不明显。效果:

被永久重定向了:

location的新地址去访问新的地方:
302:if (!ans)
{
setcode(302); // 临时重定向,每次访问到指定网址就拿到对应的location里的网址进行访问,浏览器不进行保存!
setheader("Location""http://123.249.104.207:8080/404.html");
}

telent查看:
因此总结下:
重定向就是在response的Location处放上对应的网址,还有些其他操作等等,没有响应正文。
GET与POST
获取资源(图片,视频,音频,网页… 静态资源),这里也可以上传类似post功能但是,uri是含参数的!上传资源,比如登录的时候上传账号+密码;然后服务端对应根据它进行相应的服务–>动态的(进行了交互)!举个例子:


进行交互,这里用的是post请求,服务端通过对应的正文拿到账号和密码,后执行login服务(服务端自己定义的),比如访问对应账号密码下的资源。1· 下面我们看一下利用post的请求与应答:
请求:

应答:

下面看下我们的效果:
login服务(RESTful风格的网络接口!)进行匹配构建应答即可!


2·GET请求与应答验证:
这里修改成get那么浏览器识别输入后就会按照get请求构建请求:

效果:

应答:

看一下我们抓包的结果:请求:

应答:

GET与POST特点总结:
GET:
POST:
但是,它俩都不是安全的,以明文形式在网络中传递,抓包就能获取,其中,https(有加密)>post动态交互安全>get动态交互!
fiddler:一个抓取构建好的报文的软件,fiddler抓到的报文,是已经被浏览器构建完毕的http请求,就是将来要发送到网络中的。

它的存在不就暴露了某些信息吗(尤其是post的比如登录功能等)
使用流程:
fiddler软件,然后启动:http的包的!


这样一抓取不就暴露密码了吗,因此说get和post都是不安全的(对http而言)!一般这种密码登录类似功能在网络中传播都是被加密的–>用的是https,下面我们抓取下:
fiddler默认是只抓取http,对于https我们要自己设置:




因此可以发现https是更加安全的!
我们在上面说了这样一句话:
HTTP 协议是一个无连接、 无状态的协议, 即每次请求都需要建立新的连接, 且服务器不会保存客户端的状态信息。
1· 为什么说http是无连接?
可以理解成http位于应用层,是一个
应用层协议,底层的网络层是基于tcp实现的,也就是tcp负责accept和connect,即对于长短连接是其底层tcp的说法,而它是只负责response和request的,即是没有连接而言。
2· 为什么说http无状态?
http本质就是一种“
文件”的服务器,比如每次我们请求它就是分析处理给我们找到对应文件然后发回来,自身是不会记录任何数据的,更不会记录客户端的信息(比如登录账号访问,那么你每次访问都要登录,但是这样就造成了麻烦)。
cookie:比如每次我们访问网站看视频都需要登录,此时我们第一次登录后,就可以看视频了,但是下一次希望不在登录就可以看,因此这就是
cookie机制(第一次登录后,服务器验证成功后,把对应的账号密码cookie返回浏览器储存,然后下次继续访问网站看视频,浏览器默认发送上对应的cookie,浏览器验证后成功就直接重定向到视频页面而不是登录页面)!
如图:

如何edge查找cookie信息:这里是储存在文件里:




小结下:
session:

上sessionid 去访问某资源,当服务端看到这一资源的id或者没有和对应cookie匹配,此时就重新登陆否则直接拿资源给它!
得到一个id,服务端拿着这个id给对应的用户建立一个记录(用户访问的一些资源),然后发给浏览器作为它的cookie,当下一次浏览器访问这个服务器的时候,就会自动带上这个id,然后服务器收到这个id就能找到对应的资源记录了!
被黑客盗取了,然后把这个id发给服务器,这样它就能访问之前用户访问的资源了,但是我们确实避免了黑客通过单纯cookie盗号行为!
过期时间,异常检测,ip溯源,地址变更等!
-因此http引入的cookie与session就减低了它的无连接,无状态的弊端!
如果想更深入了解cookie与session,有机会博主后再次更新专门一篇讲解它俩!
简单的http服务器视频效果展示下面我们基于上面所叙述的http方面的知识来简单实现的http版服务器,具有跳转,重定向,动态交互等功能,然后在登录页面密码只要是666就能正确登录并跳转视频播放页面,否则就404页面!
简单HTTP服务器功能测试效果
源码http协议的内容,明白了它的概念,结构等等,以及自己手搓实现了简单版的http服务器,当然前提还得是对http相关知识掌握牢固,其次就是考验代码能力了,博主在学习http专题时候历经一个星期多,从学习到编写对应代码,也陷入过对应的几个小时找bug环节,但是最终由于那份坚持还是完成了任务,此篇,博主通过自己整理的笔记再一次书写成博客耗时半天,重温了一遍知识就是很爽~,也希望对大家学习http有帮助!苦尽甘来时,再讲来时路! 冲冲冲!!!