网络协议打怪升级-应用层:HTTP、HTTPS
1.HTTP
HTTP(HyperText Transfer Protocol,超文本传输协议)是一个用在客户端和服务端之间传输数据的应用层协议,也是网络用户接触最多的协议。由于此协议很常见,本文不再赘述其结构
、核心概念
等知识,只会重点梳理协议的核心特性和协议发展。
1.1.HTTP 1.x
- HTTP 1.x的核心特性
- 请求-响应式模型:客户端发送
请求
,服务端返回响应
- 无状态:每个HTTP请求是独立的,服务器不会记住之前的请求,所以出现了Cookie、Session或者URL参数
- 文本协议:请求和响应以纯文本形式传输,(在2.x开始,使用二进制传输)
- 状态码:HTTP响应使用状态码来标识响应结果。
1 2 3 4 5
1XX:信息性(ex:101 Switching Protocols-http升级websocket协议) 2XX:成功 3XX:重定向 4XX:客户端错误 5XX:服务端错误
- 头部:提供请求元信息,包括
Content_Type
(内容类型),Host
(目标域名),User-Agent
(客户端标识),Referer
(客户端域名) - 超文本支持:最初设计传输HTML,后续支持图片,JSON,视频等任意数据
- 请求-响应式模型:客户端发送
- HTTP 1.x流程
- HTTP 1.x基于TCP协议,在TCP完成三次握手建立连接后,HTTP连接建立在TCP连接之上
- HTTP 依赖DNS协议和IP协议,通过DNS协议解析URL到IP,TCP协议依赖IP协议进行包传递
- HTTP 1.x不同版本之间差异
HTTP 0.9
- 最早版本,用于简单网页传输
- 只支持
GET
,用于获取资源 - 单次连接:每次请求都要建立一个TCP连接
- 只传HTML,且无状态码,无法区分成功或错误
HTTP 1.0
- 增加
POST
,HEAD
(仅获取头部) - 增加请求头,允许携带元信息
- 引入状态码
- 支持非HTML传递,由于请求头中
Content_Type
指定类型
- 增加
HTTP 1.1及之后
- HTTP 1.1奠定了当前HTTP1.x协议的基本特性
持久化(keep-alive)
允许多个HTTP请求复用一个TCP连接- 强制头部,要求请求必须包含一些特定字段(如Host)
管道化(pipline)
允许收到前一个请求的响应前发送后续请求,减少等待时间
在1997年HTTP1.1之后,HTTP1.x稳定运行了十多年。 但是随着现代更复杂的网页出现,人们对高延迟网络(如移动网络)的优化需求。2015年,HTTP2正式被推出。
1.2.HTTP 2
1
HTTP/2旨在提升性能、降低延迟并适应现代化Web需求,而不改变HTTP的语义(如方法、状态码、URI),保持与HTTP1.x的兼容性
1.2.1HTTP 2解决了什么问题?
在说明HTTP 2解决了哪些问题之前,我们先看看HTTP1.x有哪些问题
- 1-队头阻塞
- 每个TCP连接一次只能处理一个请求-响应对,即使启用Pipeline,响应仍需按序返回,若某一个请求或响应延迟(比如满加载图片),后续请求会被阻塞
- 浏览器为了解决这个问题,允许开启多个TCP连接(默认6个),但却增加了服务器的负担
- HTTP 2的解决办法:多路复用(multiplexing)
- 允许在单个TCP连接上并行传输多个请求和响应
- 每个请求是一个独立的”流”,互相不干扰,消除了队头阻塞
- 2-头部冗余和高额开销
- 每个请求重复发送大量头部(如User-Agent,Accept),且未压缩,浪费带宽
- HTTP 2的解决办法:头部压缩(HPACK)
- 使用专门的压缩算法,使用动态表记录已发送的头部,后续只传输差异或索引
- 3-连接效率低
- 尽管有keep-alive,仍需要多个连接,每个连接需三次握手和慢启动,延迟增加
- HTTP 2的解决办法:单一连接
- 由于多路复用的存在,所有请求可以公用同一个TCP连接,减少握手和资源开销
- 4-服务器推送支持度不高
- 使用请求-响应式模型,客户端必须对所有资源进行请求,增加往返时间
- HTTP 2的解决办法:服务器推送(server push)
- 服务器可以主动推送相关资源到客户端,减少请求次数,减少客户等待时间
1.2.2HTTP 2的核心技术特点
- 二进制协议:使用二进制传输代替HTTP1.x的纯文本传输,解析更快、更高效
- 多路复用:多个HTTP请求/响应可以使用同一个TCP连接,每个请求是一个独立的”流”,彼此之间互不干扰
- 头部压缩:使用特殊算法压缩头部,维护一张动态表记录已发送的头部,减少带宽使用
- 服务端主动推送:打破了之前的请求-响应式模型,允许一次请求多个响应
- 向后兼容:保留HTTP1.x的语义,无感向后兼容
2.HTTPS
随着互联网世界的不断扩展,传输安全性也称为互联网设计者们必须要考虑的课题。 对于客户端-服务端这种交互形式来说,需要考虑的安全问题主要有以下几点:
- 传输包内容被劫持
- 传输包内容被修改
- 服务端的可信任性
HTTPS的出现,正是为了解决上面三个问题。
2.1.HTTPS的握手流程
我们都知道,HTTPS使用SSL、TLS协议来保证请求的安全性。 那么SSL
和TLS
是什么呢?
SSL和TLS是两个在传输层之上,在应用层之下的协议。
旨在解决HTTP请求中的安全问题,TLS/SSL在TCP连接建立后(三次握手),
通过握手过程协商加密参数,然后加密TCP数据流。
当前HTTPS几乎完全使用TLS,尤其是TLS1.2,TLS1.3,SSL已经基本被淘汰。
原因是TLS相较于SSL,有更强大的加密算法和更安全的加密套件,
在性能上的表现也是TLS优于SSL,TLS成为了HTTP加密行业的新标准
TLS是如何使请求变得安全呢?答案就在HTTPS的握手过程中
TLS握手过程如下:
- 客户端hello,携带请求信息
- TLS版本
- 客户端随机数,用于生成密钥
- 支持的加密套件列表
- 扩展字段(如支持的椭圆曲线、ALPN协议)
- 服务端hello,携带响应信息
- 选定的TLS版本
- 服务端随机数,用于生成密钥
- 选定的加密套件
- 扩展响应
- 服务端发送证书信息,供客户端验证服务端安全
- 服务器的公钥证书(CA颁发)
- 可选:证书链
- 服务端发送Done
- 空消息,表示服务器完成发送
- 提示客户端开始响应
客户端收到证书信息,通过证书公钥加密并验证证书可信任性
- 客户端验证通过,生成预主密钥与通信密钥,并发送预主密钥
- 生成预主密钥
- (预主密钥+客户端随机数+服务端随机数)三个密钥生成通信密钥
- 此时客户端持有通信密钥
- 发送预主密钥到服务器
- 服务端收到预主密钥
- (预主密钥+客户端随机数+服务端随机数)三个密钥生成通信密钥
- 此时服务端持有通信密钥
- 服务端和客户端分别发送一条短消息
- 切换到加密模式
- 表示后续通信将使用协商好的通信密钥进行加密
- Server Finish && Client Finish
- 使用通信密钥加密的校验消息,包含握手中所有消息的哈希
- 验证握手完整性
- 确认双方密钥一致
至此,后续在此连接上发送的数据包都通过通信密钥进行堆成加密,解决了:
1-数据包被劫持:数据被加密,劫持了也没有密钥进行解密 2-服务端可信任性:通过校验CA颁发的证书,保证服务端是CA认可的、可信任的服务器
如何避免数据包被篡改?
TLS使用消息认证码MAC(Message Authentication Code)来确保数据完整性
MAC:
1-数据在进行发送之前,基于通信密钥,计算发送数据包中所有内容的MAC(基于HMAC,如HMAC-SHA256),并放到请求中。
2-数据接收到之后,先解密,然后基于通信密钥对解密后的内容计算MAC。
3-比较两个MAC是否一致,若不一致,说明数据被篡改。
3.补充:SSE与WebSocket
SSE与WebSocket都是基于HTTP的通信机制,用于实现服务器与客户端之间的实时数据传输。他们在HTTP基础上扩展了功能,解决了HTTP 1.x的请求-响应模型在实时性上的缺陷
3.1.SSE
SSE(Server Send Event)是一种基于HTTP的技术,允许服务端向客户端推送实时更新。它使用标准的HTTP协议,通过Content-Type=text/event-stream实现单向数据流。
实现原理:
- 连接建立
- 客户端发送HTTP请求,头部包含Accept:text/event-stream
- 服务端响应Content-Type:text/event-stream,保持连接不关闭
- 服务端推送消息
- 服务端发送的消息遵循简单文本格式,每条消息以换行符’\n’分隔
- event: [时间类型]:指定事件名
- data: [数据]:实际数据
- id:[标识]:事件id
- 空行:’\n\n’:标识一条消息结束
- 服务端发送的消息遵循简单文本格式,每条消息以换行符’\n’分隔
- 客户端按照空行为分割一个个接收服务端返回的数据并处理
- 重连机制:如果连接断开,
EventSource
会根据retry:
(服务器指定重试间隔)字段自动重连
特性:
- 长连接:HTTP连接保持开放,服务器分块推送
- 简单:基于HTTP,无需额外协议
- 单向性:仅服务器推送,客户端无法通过同一连接发送数据
常见用法:
- 实时消息推送(新闻、股票)
- 状态更新(服务器状态更新)
- 聊天模型流式返回
3.2.WebSocket
WebSocket与SSE不同,它是一种基于TCP的独立的协议,通过HTTP握手建立,提供全双工通信(客户端和服务端可同时发送消息)
它在建立连接时,依赖HTTP发起握手(Upgrade请求),完成后切换为WebSocket的独立协议
实现原理:
- 握手过程
- 首先,客户端与服务端建立TCP连接
- 客户端发送HTTP请求,包含头部升级
GET /chat HTTP/1.1 Host: example.com Upgrade: websocket ...
- 服务端响应101 Switching Protocols,确认升级
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade ...
- 消息传输:WebSocket连接建立后,通过二进制帧通信
- FIN:是否最后一帧
- Opcode:帧类型(0x1文本,0x2二进制,0x8关闭)
- Payload:实际数据
- 双向通信:
- 客户端和服务端可随时发送消息,无需等待对方响应
特性:
- 协议升级:从HTTP升级为WebSocket
- 全双工:双向实时通信
- 高效:二进制帧减少开销
常见用法:
- 实时双向交互:在线聊天
- 游戏:实时同步玩家操作和状态
- 物联网:设备与服务器的双向通信
4.总结
- HTTP1.x/HTTP2
- 是应用层的协议,用来实现客户端与服务器的交互
- 有多个请求方法和响应CODE,用来标识不同类型的请求和不同类型的响应
- 请求头中包含元数据,标识请求类型、携带参数类型、请求源、目标服务器地址等
- HTTP 1.x 纯文本传输,仅支持请求-响应式模型,可以通过keep-alive实现多个请求复用同一TCP连接,但是会有队头阻塞等问题
- HTTP 2二进制帧传输;支持服务端主动推送;采用多路复用,每个请求被分为特定的流,可以不按照顺序进行传输;支持头部压缩,减少请求包大小,降低带宽压力
- HTTPS
- 使用TLS/SSL协议,实现传输内容安全(加密),服务器可信任(证书校验),传输内容防篡改(MAC)
- 在TCP连接建立后,通过TLS/SSL的握手流程,实现对称密钥商议和证书的验证
- HTTPS需要客户端和服务端都同时支持,单边支持无法使用HTTPS
- SSL VS WebSocket | 特性 | SSE | WebSocket | | — | — | — | | 通信方向 | 单向 | 双向(全双工) | | 协议基础 | HTTP | HTTP握手后建立独立协议 | | 数据格式 | 文本(event-stream) | 二进制帧(支持文本/二进制) | | 连接方式 | 长连接 | 持久连接 | | 复杂度 | 简单 | 较复杂 | | 重连 | 内置支持 | 需手动实现 |