目录
1.前言
哈喽大家好啊,今天来继续给大家带来Java中网络原理的学习,本节主要学习的是HTTP协议,在讲HTTP协议之前还会补充一个知识点(自定义协议),本节学完后就是HTTPS的学习了,那么废话不多说让我们开始吧。
2.正文
2.1自定义协议
在平时写代码的时候,咱们往往跟应用层打交道,应用层中涉及到的网络通讯协议,很多都是程序员自己定制的。那么到底如何自定义协议呢?
自定义协议,分成两个阶段:
- 根据需求, 明确传输哪些信息
- 约定好信息组织的格式.
其中有许多组织信息的格式,主要包含以下四种:
设计协议时,数据组织格式直接影响可读性、传输效率、解析复杂度。以下通过生活化案例,对比四种常见格式:行文本、XML、JSON、Protobuf。
1. 行文本格式
特点:用简单分隔符(如逗号、竖线)组织数据,适合结构简单的场景。
类比:快递单上的信息——用空格或横线分隔收件人、电话、地址。示例:用户登录协议
login|user123|e10adc3949ba59abbe56e057f20f883e|mobile
字段解释:
login
:命令类型(登录)
user123
:用户名
e10adc...
:MD5加密后的密码
mobile
:设备类型优点:
体积小,解析简单(直接按分隔符拆分)。
适合嵌入式设备或性能受限的场景。
缺点:
扩展性差(新增字段需调整解析逻辑)。
无数据类型区分(所有内容都是字符串)。
2. XML格式
html 和 xml 都是成对的标签构成的键值对结构~
html 标签内容都是固定的。大佬们约定好的,你不能乱写,也不能创建新的标签(现在 html5 允许自定义标签了)xml 标签内容是自定义的。特点:通过标签嵌套表示数据,适合复杂结构化数据。
类比:书本目录——用章节标题和子标题分层组织内容。示例:订单数据传输
<order> <id>1001</id> <customer> <name>张三</name> <phone>13800138000</phone> </customer> <items> <item> <product_id>P100</product_id> <quantity>2</quantity> </item> <item> <product_id>P200</product_id> <quantity>1</quantity> </item> </items> </order>
优点:
结构清晰,支持嵌套和复杂数据类型。
可读性强(标签自带语义)。
缺点:
冗余标签多,体积大(传输效率低)。
解析复杂。
现在xml使用的已经很少了,主要是下面的json。
3. JSON格式
特点:轻量级的键值对结构,兼顾可读性和简洁性。
类比:表格简历——用“字段名:值”清晰展示信息。示例:用户消息推送
{ "type": "message", "sender": "user123", "receiver": "user456", "content": "晚上一起吃饭吗?", "timestamp": 1629780000, "extras": { "emotion": "开心", "priority": 1 } }
优点:
语法简洁(比XML体积小)。
天然支持嵌套对象和数组。
广泛支持(几乎所有编程语言都有解析库)。
适用场景:
RESTful API 接口(90%的互联网API使用JSON)。
前端与后端数据交互。
4. Protobuf(Protocol Buffers)(C++用的比较多)
特点:二进制编码,高性能,需预定义数据结构(
.proto
文件)。
类比:密码本——收发双方需提前约定编码规则,传输时用二进制压缩。优点:
体积极小(比JSON小3-10倍)。
解析速度极快(无需反射,直接内存映射)。
强类型约束(减少数据错误)。
缺点:
可读性差(二进制不可直接阅读)。
需预编译生成代码(开发流程稍复杂)。
总结一下:
- 行文本 (最原始)
- xml(比较原始,可读性好,冗余较多)
- json(主流的方式,可读性好,冗余一般)
- protobuf(高性能场景下使用的方式,可读性差,冗余最小)
格式 体积 可读性 解析速度 适用场景 行文本 最小 低 快 简单配置、传感器数据 XML 大 高 慢 复杂企业级系统 JSON 中等 高 中等 Web API、前后端交互 Protobuf 最小 低 最快 高性能通信、IoT、微服务
下文就要展开我们的重点HTTP协议了。
2.2HTTP协议
HTTP是一问一答模式的协议,客户端发来一个请求,服务器就返回一个响应,请求和响应一一对应。对于HTTP协议的学习我们需要借助抓包工具来进行。
2.2.1抓包工具
抓包工具是什么呢?是用来干什么的呢?
1. 什么是抓包?
抓包(Packet Capture)指捕获网络传输中的数据包,并对其进行分析的过程。
就像在快递运输线上安装监控摄像头,记录每个包裹的来源、目的地和内容。
2. 为什么需要抓包?
有以下几个场景:
调试网络问题:定位连接超时、丢包等问题。
分析协议行为:查看HTTP请求、DNS解析等细节。
安全审计:检测恶意流量(如DDoS攻击、数据泄露)。
性能优化:分析网络延迟、带宽占用。
3. 抓包工具的工作原理
网卡混杂模式:
默认情况下,网卡只接收目标地址是自己的数据包。
开启混杂模式后,网卡会捕获流经它的所有数据包(包括其他设备的流量)。
协议解析与过滤:
抓包工具根据协议规范(如TCP/IP、HTTP)解析二进制数据包,提取可读信息。
支持按协议类型、IP地址、端口号等条件过滤数据。
存储与展示:
数据包可保存为文件(如
.pcap
格式),供后续分析。工具提供可视化界面,展示数据包的层次结构和字段内容。
讲完了什么是抓包,接下来介绍两个抓包工具:
1.Wireshark
官网:Wireshark · Go Deep
https://www.wireshark.org/
核心功能:
多协议支持:解析超过2000种协议(如HTTP、TCP、DNS、ICMP)。
深度分析:展示数据包的每一层(从物理层到应用层)。
过滤与统计:支持复杂过滤语法,提供流量统计图表。
2.Fiddler
官网:Web Debugging Proxy and Troubleshooting Tools | Fiddler
https://www.telerik.com/fiddler
核心功能:
HTTP/HTTPS代理:拦截所有经过代理的Web请求。
请求/响应修改:实时修改请求参数、响应内容。
性能分析:统计页面加载时间、资源大小。
自动化脚本:通过Fiddler Script自定义处理逻辑。
二者对比:
简而言之:wireshark抓很多协议,使用门槛较高。而fiddler专门抓HTTP,功能简单,使用也简单。
对比维度 Wireshark Fiddler 协议支持 所有网络层协议(TCP/IP、ICMP、ARP等) 主要HTTP/HTTPS,部分FTP、WebSocket 抓包层级 底层(原始数据包) 应用层(HTTP请求/响应) 操作系统 跨平台(Windows、macOS、Linux) 仅Windows(经典版) 性能影响 高(捕获所有流量) 低(仅代理流量)
这里我们往后就使用fiddler。
2.2.2请求响应格式
这里我们通过fiddler来抓一个请求与响应:
请求:
- 首行:请求方法 URL 版本号
- 请求头(header):键值对结构,每一行是一个键值对,键和值之间使用:空格 分割,HTTP 请求头中的键有哪些取值,对应的值又有哪些取值,都是由标准约定的。
- 空行:用来标识header结束了。
- 正文(body):部分请求有正文,部分没有(像上面这个就没有)。
响应:
- 首行
- 响应头:也是键值对
- 空行:表示header部分结束/
- 正文
下文我们要讲解写请求与相应的关键属性。
2.2.2.1URL
URL(Uniform Resource Locator,统一资源定位符)是互联网上资源的唯一地址,用于定位网页、图片、API 等资源。
类比:就像现实中的“快递地址”,告诉浏览器如何找到目标资源。
一个典型的 URL 格式如下:
https://www.example.com:8080/path/to/page?name=John&age=30#section1
分解为以下核心部分:
[协议]://[域名]:[端口]/[路径]?[查询参数]#[锚点]
- 协议:定义客户端与服务器之间的通信规则。
- 域名:将 IP 地址(如
192.168.1.1
)转换为易记的名称。- 端口:标识服务器上的具体服务(类似“门牌号”)。
- 路径:指定服务器上的资源位置(类似文件路径)。
- 查询参数:向服务器传递附加参数,格式为
key=value
。- 锚点:定位页面内的特定位置(不会发送到服务器)。
2.2.2.2urlencode
为了给大家更好展示urlencode是什么,这里附上实际例子,我在浏览器搜索你好。
可以看到:
https://www.sogou.com/web?query=%E4%BD%A0%E5%A5%BD&_ast=1745143368&_asf=www.sogou.com&w=01029901&p=40040100&dp=1&cid=&s_from=result_up&sourceid=5_01_03&sessiontime=1745143614785
我们去实际抓包:
可以看到搜多的字符串均被转义。
URL编码(Percent-Encoding)是一种将特殊字符和非ASCII字符转换为安全格式的机制,确保URL在互联网中正确传输和解析。
为什么需要URL编码?
URL 中本身就有一些特殊符号,代表不同的特殊含义。query string 的内容都是程序员自定义的万一 query string 里也包含了特殊含义的符号咋办?所以就需要URL编码
urlencode 把数据的二进制内容,每个字节取出来十六进制表示,前面加上%
2.2.3认识方法
方法 | 安全 | 幂等 | 典型场景 |
---|---|---|---|
GET | ✔️ | ✔️ | 获取资源 |
POST | ✖️ | ✖️ | 创建资源或触发操作 |
PUT | ✖️ | ✔️ | 替换整个资源 |
DELETE | ✖️ | ✔️ | 删除资源 |
PATCH | ✖️ | ✔️* | 部分更新资源 |
HEAD | ✔️ | ✔️ | 获取响应头信息 |
OPTIONS | ✔️ | ✔️ | 查询支持的请求方法 |
TRACE | ✔️ | ✔️ | 调试(通常禁用) |
CONNECT | ✖️ | ✖️ | 建立代理隧道(如 HTTPS) |
tips:PATCH 的幂等性需由具体实现保证。
下文讲解几个最常见的方法
2.2.3.1GET与POST
HTTP 协议中,GET 和 POST 是最常用的两种方法,它们在用途、数据传输方式、安全性等方面有显著区别。
GET:通过 URL 传递参数
格式:
http://example.com/api?name=Alice&age=30
特点:
参数可见,适合非敏感数据(如搜索关键字)。
参数会被浏览器历史记录、服务器日志记录。
POST:通过请求体传递参数
格式:参数封装在请求体中,支持多种格式(如 JSON、表单数据)。
特点:
参数不可见,适合敏感数据(如密码、支付信息)。
支持复杂数据结构(如文件上传)。
两个典型场景:
- 登录。
- 上传 =>请求带有正文的,正文就是保存了当前上传的数据的内容上述请求中,图片本身是二进制的,通过特殊方式进行转码(base64 编码,把二进制转成文本)其实 body 也是可以直接填二进制数据 ~
GET与POST对比:
- 语义上,二者可以混着用,GET与POST没有本质区别。
- 携带数据的方式上,POST也可以带有query string,GET也可以带有body
- GET常被设计成幂等,POST无要求。
- GET常认为能被缓存(幂等情况下),而POST不行。
特性 GET POST 用途 获取资源(查询数据) 提交数据(创建或修改资源) 参数位置 URL 查询字符串( ?key=value
)请求体(Body) 数据长度限制 受限(URL 长度通常 ≤2048 字符) 理论上无限制(取决于服务器配置) 缓存 可被浏览器缓存 不可缓存 幂等性 幂等(多次请求结果相同) 非幂等(多次请求可能产生不同结果) 安全性 参数明文暴露在 URL 中(需 HTTPS) 参数在请求体中(仍需 HTTPS 加密) 书签/分享 可保存为书签或分享链接 不可直接保存或分享
2.2.3.2PUT与DELETE
直接开讲:
PUT 方法
用途:完整替换资源(客户端需提供资源的全部新数据)。
特点:
幂等性:多次请求效果相同(重复替换结果一致)。
安全性:非安全操作(修改资源)。
数据位置:请求体中传递完整的资源内容。
DELETE 方法
用途:删除指定资源。
特点:
幂等性:多次删除同一资源效果相同(删除后资源不再存在)。
安全性:非安全操作(修改资源)。
数据位置:通常无需请求体,通过 URL 标识资源。
特性 PUT DELETE 目的 替换资源(全量更新) 删除资源 幂等性 ✔️(多次替换结果一致) ✔️(多次删除结果一致) 请求体 需要(包含完整新数据) 通常不需要 典型状态码 200 OK / 201 Created 204 No Content / 200 OK
这样,方法中重要的“增删改查”已经讲解完毕。
2.2.4请求头关键属性
这边也是各重头戏,讲到请求头中各种关键属性,可能跟前文会有所重复,但为了内容完整还是一并写出。
1. 键值对结构
定义:HTTP 头部以
键: 值
的形式组织,键与值之间用冒号分隔。(RFC标准文档)作用:提供标准化、可扩展的元数据传递方式。
示例:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Content-Type: application/json
注意事项:
键不区分大小写(如
content-type
与Content-Type
等效)。多个值可用逗号分隔(如
Accept: text/html, application/json
)。
2. Host
定义:指定请求的目标域名和端口(HTTP/1.1 强制要求)。
作用:
区分同一服务器上的多个网站(虚拟主机)。
帮助反向代理或负载均衡器正确路由请求。
示例:
Host: example.com:8080
场景:
访问
http://example.com
和http://anotherexample.com
时,服务器通过Host
头返回不同内容。
3. Content-Length
定义:表示请求体或响应体(body)的字节长度(十进制数字)。
作用:
服务器/客户端明确需读取的数据量,避免粘包问题。
对于
POST
或PUT
请求,必须准确计算。示例:
Content-Length: 1024
注意事项:
若使用分块传输(
Transfer-Encoding: chunked
),无需设置此头。
4. Content-Type
定义:指示请求体或响应体的媒体类型(MIME 类型)。
作用:
告知服务器如何解析请求体(如 JSON、表单数据)。
指导客户端(如浏览器)如何渲染响应内容。
常见类型:
类型
用途
text/html
HTML 网页
application/json
JSON 数据
application/x-www-form-urlencoded
表单提交(键值对)
multipart/form-data
文件上传
示例:
Content-Type: application/json; charset=utf-8
5. User-Agent
定义:标识客户端(如浏览器、爬虫)的类型和版本,里面表示了用户使用的设备的浏览器和操作系统的情况。
作用:
服务器适配不同客户端(如返回移动端页面)。
统计用户设备分布或检测恶意爬虫。
示例:
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Mobile/15E148 Safari/604.1
6. Referer
定义:表示当前请求的来源页面 URL。即这个页面是从哪个页面跳转来的。
作用:
分析流量来源(如广告点击统计)。
防盗链(限制图片仅允许从特定网站加载)。
示例:
Referer: https://www.google.com/
注意事项:
隐私模式下或某些浏览器可能不发送此头。
7. Cookie
定义:cookie 就是浏览器允许网页在本地硬盘存储数据的一种机制,而不是让网页代码直接访问文件系统(避免风险),而是做了一层抽象。Cookie 这里是按照键值对的方式来存储数据的,浏览器中可以直接看到当前页面保存的 cookie 有哪些的。浏览器保存了这些 cookie 之后,就会在后续给服务器发送请求的时候,把这些 cookie 键值对放到 请求 cookie header 中传输给服务器。
作用:
会话管理(如用户登录状态)。
个性化设置(如语言偏好、主题)。
示例:
Cookie: sessionId=abc123; theme=dark
3.小结
今天的分享到这里就结束了,喜欢的小伙伴点点赞点点关注,你的支持就是对我最大的鼓励,大家加油!