欢迎光临
我们一直在努力

应用层协议详解(含HTTP):从自定义格式到报文抓包 | 超详细图解 | 适合小白

文章目录

  • 一、应用层基础
    • 1.1 应用层概念
  • 二、应用层协议设计
    • 2.1 网络通信协议概念
    • 2.2 如何自定义协议
      • 2.2.1 明确传输内容
      • 2.2.2 约定数据格式
  • 三、常见数据组织格式
    • 3.1 行文本格式
      • 示例:请求格式
      • 示例:响应格式(商家列表)
    • 3.2 XML格式
      • 示例(请求)
      • 示例(响应)
      • 优缺点
    • 3.3 JSON格式
      • 示例(请求)
      • 优缺点
    • 3.4 Protobuf格式
      • 核心特点
      • 优缺点
    • 3.5 数据格式总结
  • 四、HTTP协议
    • 4.1 HTTP基本特点
    • 4.2 抓包工具
    • 4.3 代理机制
      • 4.3.1 正向代理
      • 4.3.2 反向代理
  • 五、HTTP报文结构(重点)
    • 5.1 HTTP请求响应报文结构
      • 5.1.1 报文字段详解
      • 5.1.2 URL编码
      • 5.1.3 HTTP请求方法
      • 5.1.4 Host 字段
      • 5.1.5 Content-Length 字段
      • 5.1.6 Content-Type 字段
      • 5.1.7 User-Agent 字段
      • 5.1.8 Referer 字段
      • 5.1.9 Cookie 字段

一、应用层基础

1.1 应用层概念

应用层是计算机网络体系结构(如TCP/IP模型或OSI模型)中的最高层,也是直接与用户应用程序交互的那一层。

应用层的核心任务就两件事: 当“快递小哥” —— 帮你把东西安全送到对方手上(怎么装车、走哪条路、送没送到,都由它管)。 当“翻译官” —— 保证双方说的是同一种语言、用同一种符号写字(你说“苹果”,对方不会听成“橘子”)。


二、应用层协议设计

2.1 网络通信协议概念

应用层中涉及到的很多网络通信协议是程序员自己定义的。

2.2 如何自定义协议

主要分为两个阶段:

2.2.1 明确传输内容

根据需求,明确要传输哪些信息。

2.2.2 约定数据格式

约定好信息组织的格式。

例如:点外卖 阶段1 = 决定外卖订单上该写哪些项目(用户、地址、餐品、价格…) 阶段2 = 决定这些项目按什么顺序、用什么分隔符、用什么语言


三、常见数据组织格式

3.1 行文本格式

示例:请求格式

用户id, 用户的位置\\n 1000, 45E45N\\n

示例:响应格式(商家列表)

一个响应由多行构成,每一行是一个商家:

商家id, 商家名称, 商家图片, 商家评分, 配送费用, 分类\\n

1, 杨国福麻辣烫, 商家图片1.jpg, 4.8, 5, 麻辣烫\\n 2, 大娘水饺, 商家图片2.jpg, 4.7, 0, 水饺\\n 3, 麦当劳, 商家图片3.jpg, 5.0, 10, 快餐\\n

注意: 实际约定时可以有很多变数。


3.2 XML格式

XML 允许你自定义标签结构,非常适合在应用层作为请求/响应的数据表示格式。它的规则由通信双方共同商定,不依赖浏览器或任何前端框架。

示例(请求)

<request>
<userid>1000</userid>
<position>75E75N</position>
</request>

示例(响应)

<response>
<shop>
<id>1</id>
<name>杨国福</name>
<image>1.jpg</image>
<rank>5.0</rank>
<sendprice>5</sendprice>
</shop>
</response>

优缺点

优点:可读性好 缺点:冗余信息多,占用带宽大


3.3 JSON格式

JSON 在可读性和带宽消耗之间取得了较好的平衡,因此成为当前最流行的应用层数据组织方案。 但追求极致性能的场景仍会选择更紧凑的二进制格式(如 Protobuf)

示例(请求)

{
"userId": 1000,
"position": "75E75N"
}

优缺点

优点:可读性好、比XML更省带宽 缺点:仍有一定冗余


3.4 Protobuf格式

核心特点

基于二进制、无冗余信息

优缺点

优点:最省带宽、解析速度快 缺点:可读性差、调试困难


3.5 数据格式总结

根据图片内容,对四种数据组织格式的总结如下:


格式特点可读性冗余适用场景
行文本 最原始的方式,用分隔符(逗号、换行等)组织数据 较好 较多 简单命令、早期协议
XML 比较原始,成对标签构成键值对结构,可自定义标签 较多(冗余信息多,浪费带宽) 企业级集成(SOAP、XMPP),但已逐渐被替代
JSON 当下主流的方式,键值对 + 数组,结构清晰 一般(仍有键名、引号、括号等冗余) Java Web 开发的基本盘,Spring / Spring Cloud 等框架都基于 JSON
Protobuf 高性能场景使用,二进制压缩,无冗余 最小(最省带宽) 性能要求高的场景(如 C++ 注重效率的项目)

选择格式取决于场景:调试友好选 JSON/XML,极致性能选 Protobuf,极简场景可用行文本。Java Web 开发以 JSON 为主流,C++ 高性能系统更倾向 Protobuf。


四、HTTP协议

4.1 HTTP基本特点

一问一答的请求-响应模式,请求和响应一一对应。


4.2 抓包工具

作用

获取网络数据包并解析报文格式

原理

抓包工具相当于一个代理,放在客户端和服务器之间,把经过的请求和响应都拦截并展示出来。

例如:你(客户端)想访问某个网站(服务器),数据包实际上经过了抓包工具(如 Wireshark、Charles、Fiddler),工具可以复制一份数据给你看,同时转发给服务器。


4.3 代理机制

4.3.1 正向代理

代表客户端干活。 客户端不直接访问服务器,而是把请求发给代理服务器,代理服务器再去访问目标服务器,然后把结果返回给客户端。

特点:服务器不知道真正的客户端是谁,只知道代理服务器。

举个例子 我(客户端)→ 我妹妹(正向代理)→ 超市老板(服务器) 我妹妹代表我去买东西,老板以为是我妹妹要买,实际上是我。

4.3.2 反向代理

代表服务器干活。

客户端不知道真正提供服务的服务器是哪台,它只知道反向代理的地址。反向代理把请求转发给后端的真实服务器,再把响应返回给客户端。 举个例子 你(客户端)还是想去那家公司办事。 公司门口设了一个前台接待员(反向代理)。 你走到前台,说“我要办某某业务”。前台去后面找一个员工(真实服务器)帮你处理,然后把结果转交给你。 你全程只跟前台说话,你根本不知道帮你办事的员工是张三、李四还是王五,也不知道背后有多少个员工。


五、HTTP报文结构(重点)

例如 使用fiddler进行抓包: 对搜狗网页进行抓包 在这里插入图片描述

5.1 HTTP请求响应报文结构

请求报文结构

1. 首行(请求行)
2. 请求头(多个键值对)
3. 空行(一个空行,标志头部结束)
4. 正文(可选,比如 POST 请求的表单数据或 JSON)

请求页: 在这里插入图片描述


响应报文结构

1. 首行(状态行)
2. 响应头(多个键值对)
3. 空行(一个空行,标志头部结束)
4. 正文(可选,比如 HTML 页面、JSON 数据等)

响应页 在这里插入图片描述


5.1.1 报文字段详解

一个完整的URL(统一资源定位符),其标准结构如下:

protocol://hostname:port/path?query#fragment

协议 (Protocol/Scheme) 定义了访问资源所遵循的规则,决定了浏览器与服务器之间的沟通方式。常见的协议包括:

http / https:超文本传输协议,用于访问网页。https 中的 ‘s’ 代表安全,会对数据加密。

ftp:文件传输协议,用于上传或下载文件。


主机名 (Hostname) 资源所在的服务器地址,可以是域名(如 cn.bing.com)或IP地址(如 192.0.2.1)。域名需要通过DNS(域名系统)解析为IP地址才能访问。


端口号 (Port) 服务器上用于特定网络服务的“入口”。正如你注意到的关键点:如果未指定,则会使用默认端口,其中http是80,https是443。 例如 https://cn.bing.com/search 等同于 https://cn.bing.com:443/search。


路径 (Path) 资源在服务器上的具体位置,通常由/分隔,层级清晰。

以/结尾,通常指向一个目录或文件夹。

不以/结尾,则往往指向一个具体文件。例如,/search 就像在告诉服务器:“请调用‘search’这个功能”。


查询字符串 (Query String) 以?开头,用于向服务器发送额外参数,常出现于搜索结果页或动态页面。其结构是键值对(key=value),多个参数间用&连接。

例如 ?wd=URL&rsv_spt=1 表示两个参数:第一个wd的值为URL,第二个rsv_spt的值为1。


片段标识符 (Fragment) 以#开头,用于定位页面内的某个特定位置。 例如: #section1 会直接滚动到页面上id为section1的部分。这部分不会被发送到服务器,仅供浏览器内部使用


举个例子:必应搜索蓝桥杯的URL

https://cn.bing.com/search?q=%E8%93%9D%E6%A1%A5%E6%9D%AF&form=SWAUA2

https: 协议名称 cn.bing.com: 要访问服务器的IP地址或域名 search:带有层次结构的路径 q=%E8%93%9D%E6%A1%A5%E6%9D%AF&form=SWAUA2:查询字符串(query String ),对要访问的资源进行补充说明。


5.1.2 URL编码

也叫百分号编码,就是把URL里那些有特殊含义的符号、或者非英文字母(比如中文)转换成一种“%+两个十六进制数”的格式,保证网络传输时不会被误解。

例如 搜索a&b

加粗样式 这里看见&被编码成了%26,查看UTF-8码表也是对应上了。 在这里插入图片描述


5.1.3 HTTP请求方法

方法说明支持的 HTTP 协议版本
GET 获取资源 1.0、1.1
POST 传输实体主体 1.0、1.1
PUT 传输文件 1.0、1.1
HEAD 获得报文首部 1.0、1.1
DELETE 删除文件 1.0、1.1
OPTIONS 询问支持的方法 1.1
TRACE 追踪路径 1.1
CONNECT 要求用隧道协议连接代理 1.1
LINK 建立和资源之间的联系 1.0
UNLINE 断开连接关系 1.0

最常用的就是 GET 和 POST。 GET 与 POST 的对比表格:

对比维度GETPOST
请求体 (body) 一般没有
数据传递位置 URL 查询字符串 (query string) 请求体 (body)
长度限制 有(浏览器/服务器限制,通常几KB) 无(可上传大文件)
安全性 数据暴露在地址栏、历史记录、服务器日志中,不适合敏感信息 数据不在 URL 中,相对安全(但仍需 HTTPS 加密)
缓存 可以被浏览器缓存 默认不被缓存
收藏夹 / 书签 可以保存为书签(包含完整参数) 不能保存为书签(不包含请求体)
典型用途(语义上) 获取资源:HTML、CSS、JS、图片、搜索查询等 提交数据:登录表单、上传文件、创建/更新资源
是否幂等 是(多次请求结果相同,不改变服务器状态) 否(多次请求可能产生多次资源创建)
实际开发灵活性 有时也用来提交少量非敏感数据(不推荐但可行) 也可以只获取数据(如通过 body 传递复杂查询条件,但不符合语义)

注:幂等指连续执行多次请求的效果与执行一次相同。GET 通常用于只读操作,因此是幂等的;POST 可能创建多个资源,不是幂等的。


5.1.4 Host 字段

表示服务器主机的地址和端口。

注意: URL 的域名:用来找到 IP 地址(路由 + DNS)。 请求头里的 Host:用来告诉服务器你要访问这个 IP 上的哪个具体网站(因为一个 IP 可以挂很多网站)。


5.1.5 Content-Length 字段

表示请求体(body)的字节长度。单位是字节。


5.1.6 Content-Type 字段

表示请求的body中的数据格式。提示了接收方如何解析body中的数据。


5.1.7 User-Agent 字段

表示了用户使用的设备浏览器和操作系统的情况。

例如

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0

各部分的含义:

字段片段含义
Mozilla/5.0 兼容性标识(历史原因,几乎所有现代浏览器都声称是 Mozilla/5.0)
Windows NT 10.0 操作系统版本(Windows 10 / 11 都报告为 NT 10.0)
Win64; x64 系统架构(64 位 Windows)
AppleWebKit/537.36 浏览器内核(WebKit 版本)
Chrome/147.0.0.0 浏览器品牌和版本(Chrome 147)
Safari/537.36 Safari 兼容标识
Edg/147.0.0.0 Edge 浏览器版本(如果通过 Edge 访问)

5.1.8 Referer 字段

描述当前页面的来源。 直接输入url 和 点收藏栏 是没有Referer的。

示例:在必应(Bing)搜索引擎中搜索可爱头像 在这里插入图片描述

可以看见上面抓包出来了Referer,从必应页面跳转到了可爱头像页面。


5.1.9 Cookie 字段

为什么需要 Cookie? JS 的限制:浏览器中的 JavaScript 代码无法直接访问用户硬盘的文件系统。 原因:这是一种安全限制(“紧箍咒”),防止恶意 JS 读取或篡改本地文件,从而保护用户隐私和系统安全。


Cookie是什么? **浏览器允许网页在本地硬盘存储少量数据的一种机制。**它不是让网页代码直接访问文件系统,而是提供了一层抽象的数据存储接口。Cookie 采用键值对(key=value)的方式存储数据

例如:登录流程(首次验证) 全过程流程图: 在这里插入图片描述

实线箭头(->)表示请求 虚线箭头(–>>)表示响应 自循环(Server->>Server)表示服务器内部处理

1.用户提交登录信息 用户在登录页面输入用户名/密码,浏览器通过 POST 请求发送给服务器。

2.服务器验证身份 服务器查询数据库,检查用户名密码是否有效。

3.验证成功后的操作(关键步骤) 生成 sessionId:使用 UUID 等算法生成一个不易猜测的随机字符串。

创建 session 对象:在服务器内存(或专用存储)中新建一个 Session 对象。

保存用户数据:将当前登录用户的关键信息(如 userId、userName)存入该 Session 对象。

建立映射:以 sessionId 为 key,Session 对象为 value,存入服务器的全局哈希表(或 Redis 等存储)。

下发 cookie:服务器通过响应头 Set-Cookie: sessionId=xxxx 告知浏览器保存这个 sessionId。

浏览器保存 cookie 浏览器收到响应后,将 sessionId=xxxx 以 Cookie 形式存储(默认绑定当前域名)。

后续请求(自动认证) 用户再次访问同一域名下的任何页面时,浏览器自动在请求头中携带 Cookie: sessionId=xxxx。

服务器收到请求后: 从 Cookie 中提取 sessionId。

在本地的哈希表(或 Redis)中查找该 sessionId 对应的 Session 对象。 如果找到,直接从中取出用户信息(如 userId),就知道“这个请求是哪个用户发来的”。 无需让用户重新登录。

Set-Cookie 是一个 HTTP 响应头字段,由服务器发给浏览器,作用是“让浏览器在本地保存一个 Cookie”。 Session:服务器端为每个用户会话创建的对象,用于存储该用户的私有数据(如用户ID、昵称、权限等)。 SessionId:一个全局唯一的随机字符串(通常用 UUID 算法生成),作为 Session 对象的钥匙。


简短总结流程图如下: 在这里插入图片描述


学习路上一起进步,如果觉得内容不错,记得点赞支持一下,也可以关注我,后续持续分享高质量技术文章!

赞(0)
未经允许不得转载:171主机测评 » 应用层协议详解(含HTTP):从自定义格式到报文抓包 | 超详细图解 | 适合小白
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址