3.http
1.基础
1.1.介绍
HTTP协议即超文本传送协议(Hypertext Transfer Protocol),是建立在TCP协议之上的一种应用层协议,是Web联网的基础。
HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接,因此HTTP连接是一种"短连接"。
1.2.tcp与http的关系
- TCP是底层通讯协议,定义的是数据传输和连接方式的规范
- HTTP是应用层协议,定义的是传输数据的内容的规范
- HTTP协议中的数据是利用TCP协议传输的,所以支持HTTP也就一定支持TCP
- HTTP支持的是web服务,而TCP/IP是协议它是Internet国际互联网络的基础。TCP/IP是网络中使用的基本的通信协议。
- TCP/IP实际上是一组协议,它包括上百个各种功能的协议,如:远程登录、文件传输和电子邮件等, 而TCP协议和IP协议是保证数据完整传输的两个基本的重要协议。通常说TCP/IP是Internet协议族,而不单单是TCP和IP。
1.3.协议发展
- 1991 HTTP/0.9
- 1996 HTTP/1.0
- 1997 HTTP/1.1
- 2009 Google 设计了基于TCP的SPDY
- 2013 QUIC
- 2015 HTTP/2
- 2018 HTTP/3
1.3.1. http 0.9
早期版本,只支持GET方法,只支持文本,短连接,每次发送请求后就释放连接。
1.3.2. http 1.0
支持GET、POST、HEAD等方法,支持MIME(所有文件格式),新增功能还包括状态码、多字符集支持、多部分发送、权限、缓存、内容编码。 客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接,性能不高。
1.3.3. http 1.1
依旧是目前使用最多的http协议。
- 新增请求方法:PUT、PATCH、HEAD、 OPTIONS、DELETE。
- 【重要】引入持久连接(persistent connection),默认开启 Connection: keep-alive,即TCP连接默认不关闭,一个连接可以被多个请求复用。
- 【重要】管道机制:可以在一次连接中处理多个请求,并且多个请求可以重叠进行,不需要等待一个请求结束后再发送下一个请求。实际中限制多,并未广泛使用。
- 【重要】分块传输编码:
- 背景:请求的编码实体资源尚未全部传输完成之前,浏览器无法显示请求页面。于是,1.1在1.0内容编码的基础上,提出了分块传输编码。 这样在传输大容量数据时,通过便可以把数据分割成多块,让浏览器逐步显示页面。
- 如何使用分块传输编码: Transfer-Encoding: chunked
- 如何确定传输已结束:每一块都会用十六进制来标记块的大小,而实体主体的最后一块会使用"0"来标记表示结束
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
25
This is the data in the first chunk
1C
and this is the second one
3
con
8
sequence
0
1.3.4. http 2.0
- 多路复用。在同一个TCP连接中,可以发送多个HTTP请求,而且请求的响应不依赖于前一个请求。每个请求单独处理,不会出现HTTP1.1中上一个请求没有回应便一直等待的情况。
- 头部压缩。当前我们在head上做了非常多的处理,导致头部过重,经过压缩后最多可压缩90%以上,降低带宽。客户端和服务端都会有一个预定的61个静态表,服务端维护动态表记录不在静态表的被压缩的头信息。
- 二进制分帧。将数据拆分为更小的帧,提高数据解析效率
- 轻量化服务器推送功能。替代webSocket。
1.3.5.QUIC
QUIC(Quick UDP Internet Connections, 快速UDP网络连接)是基于UDP的协议, 利用了UDP的速度和效率, 同时整合TCP, TLS和HTTP/2的优点并加以优化. 用一张图可以清晰的表示他们之间的关系。

QUIC是用来替代TCP 和 SSL/TLS的传输层协议。
我们熟知的应用层协议有HTTP, FTP, IMAP等, 理论上都可以运行在QUIC上, 其中运行在QUIC之上的协议被称为HTTP/3, 这就是HTTP over QUIC即HTTP/3的含义
QUIC 协议如何解决 TCP 的缺陷?
- 基于 UDP:绕过操作系统内核的 TCP 协议栈,避免队头阻塞。
- 0-RTT 连接:通过缓存会话密钥实现快速重连。
- 连接迁移:使用 Connection ID 而非 IP + 端口,支持网络切换不断连。
- 前向纠错(FEC):发送冗余数据包减少重传次数。
1.3.6.http 3.0
HTTP3是在保持QUIC稳定性的同时使用UDP来实现高速度(选择QUIC就是选择UDP), 同时又不会牺牲TLS的安全性。【是的,3.0放弃TCP,选择了UDP】
1.4.MIME
资源实际上是一种承载着某种信息的数据,相同的信息可以采用不同形态的数据来展现,数据的"形态"主要体现为展示数据所采用的格式, 比如一个数据对象可以通过XML格式来表示,也可以通过JSON格式来表示。数据的处理必须依赖于一种已知的格式,所以将Web资源的形态以一种标准化的方式固定下来显得尤为重要,这就是我们接下来着重介绍的媒体媒体(Media Type)。
不论是通过HTTP请求从Web服务器上获取资源,还是利用请求向服务器提交资源,响应或者请求的主体(Body)除了包含承载资源本身的数据之外,其报头(Header)部分还应该包含表示数据形态的媒体类型。
媒体类型又被称为MIME(Multipurpose Internet Mail Extension)类型,MIME是一个互联网标准,它扩展了电子邮件标准, 使其能够支持非ASCII字符、二进制格式附件等多种格式的邮件消息。由于MIME在电子邮件系统应用得非常好,所以被HTTP用于描述并标记多媒体内容。 下面的列表给出了一种常用的媒体类型。
- text/html:HTML格式的文档。
- text/xml(application/xml):XML格式的文本。
- text/json(application/json): JSON格式的文本。
- image/gif(image/jpeg、image/png):GIF(JPEG、PNG)格式的图片。
- audio/mp4(audio/mpeg、audio/vnd.wave):MP4(MPEG、WAVE)格式的音频文件。
- video/mp4(video/mpeg、video/quicktime):MP4(MPEG、QUICKTIME)格式的视频文件。
1.5.HTTP方法
HTTP采用简单的请求/响应模式的消息交换旨在实现针对某个Web资源的某种操作,至于针对资源的操作类型,不外乎CRUD而已。
一个HTTP请求除了利用URI标志目标资源之外,还需要通过HTTP方法(HTTP Method或者HTTP Verb)指名针对资源的操作类型。
我们常用的HTTP方法 包括GET、POST、PUT、DELETE、HEAD、OPTIONS、TRACE、CONNECTION和PATCH等
1.6.状态码
总结:
- 2XX: 正常
- 3XX: 交给别人
- 4XX: 客户端的错。
- 400 Bad Request: 请求参数数据有问题
- 403 Forbidden:禁止访问,就是没权限
- 404 Not Found:找不到资源
- 5XX: 服务端的错
- 500 Internal Server Error:通常是服务挂了
- 502 Bad Gateway:服务正常,但是请求处理的时候出现异常。例如spring中,基础类型参数没有传入值。
1.7.浏览器请求处理过程

每个请求,使用不同的颜色标记不同的阶段:
- Resource Scheduling:阶段一:本地资源调度
- Queueing: 浏览器本地请求队列。
- Connection Start: 阶段二:建立连接
- Stalled:浏览器得到要发出这个请求的指令,到请求可以发出的等待时间,一般是代理协商、以及等待可复用的TCP连接释放的时间,不包括DNS查询、建立TCP连接等时间等。
- DNS Lookup: DNS解析查询地址
- Initial connection:初始化连接,TCP三次握手
- SSL: 建立SSL
- Request/Response 阶段三:请求与响应
- Request sent:请求第一个字节发出前到最后一个字节发出后的时间,也就是上传时间
- Waiting for server response:请求发出后,到收到响应的第一个字节所花费的时间
- Content Download: 收到响应的第一个字节,到接受完最后一个字节的时间,就是下载时间
1.8.相关命令
# 1.ping 域名
[root@localhost ~]# ping -c 4 www.bilibili.com
PING a.w.bilicdn1.com (221.204.56.95) 56(84) bytes of data.
64 bytes from 95.56.204.221.adsl-pool.sx.cn (221.204.56.95): icmp_seq=1 ttl=53 time=11.2 ms
64 bytes from 95.56.204.221.adsl-pool.sx.cn (221.204.56.95): icmp_seq=2 ttl=53 time=17.2 ms
64 bytes from 95.56.204.221.adsl-pool.sx.cn (221.204.56.95): icmp_seq=3 ttl=53 time=12.9 ms
64 bytes from 95.56.204.221.adsl-pool.sx.cn (221.204.56.95): icmp_seq=4 ttl=53 time=12.9 ms
--- a.w.bilicdn1.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 11.267/13.596/17.225/2.209 ms
# 2.查询DNS。安装 yum install bind-utils
[root@localhost ~]# nslookup
## 进入查询模式,这里服务器默认使用DNS是114.114.114.114
> www.bilibili.com
Server: 114.114.114.114
Address: 114.114.114.114#53
## 以下是查询出来域名解析出来的地址(都是cdn地址)
Non-authoritative answer:
www.bilibili.com canonical name = a.w.bilicdn1.com.
Name: a.w.bilicdn1.com
Address: 123.234.3.167
Name: a.w.bilicdn1.com
Address: 123.234.3.168
Name: a.w.bilicdn1.com
Address: 221.204.56.91
## 修改DNS为8.8.8.8
> server 8.8.8.8
Default server: 8.8.8.8
Address: 8.8.8.8#53
## 再查询出来域名解析出来的地址(都是cdn地址)
> www.bilibili.com
Server: 8.8.8.8
Address: 8.8.8.8#53
Non-authoritative answer:
www.bilibili.com canonical name = a.w.bilicdn1.com.
Name: a.w.bilicdn1.com
Address: 221.204.56.93
Name: a.w.bilicdn1.com
Address: 221.204.56.95
# 3.域名注册信息。安装yum install jwhois
[root@localhost ~]# whois bilibili.com
[Querying whois.verisign-grs.com]
[Redirected to grs-whois.hichina.com]
[Querying grs-whois.hichina.com]
[grs-whois.hichina.com]
Domain Name: bilibili.com
Registry Domain ID: 133351793_DOMAIN_COM-VRSN
Registrar WHOIS Server: grs-whois.hichina.com
Registrar URL: http://www.net.cn
Updated Date: 2021-12-29T02:09:35Z
Creation Date: 2004-10-21T11:37:37Z
Registrar Registration Expiration Date: 2031-10-21T11:37:37Z
Registrar: Alibaba Cloud Computing (Beijing) Co., Ltd.
Registrar IANA ID: 420
Reseller:
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Domain Status: clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited
Domain Status: serverDeleteProhibited https://icann.org/epp#serverDeleteProhibited
Domain Status: serverTransferProhibited https://icann.org/epp#serverTransferProhibited
Domain Status: serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited
Registrant City:
Registrant State/Province:
Registrant Country:
Registrant Email:https://whois.aliyun.com/whois/whoisForm
Registry Registrant ID: Not Available From Registry
Name Server: NS3.DNSV5.COM
Name Server: NS4.DNSV5.COM
DNSSEC: unsigned
Registrar Abuse Contact Email: DomainAbuse@service.aliyun.com
Registrar Abuse Contact Phone: +86.95187
URL of the ICANN WHOIS Data Problem Reporting System: http://wdprs.internic.net/
>>>Last update of WHOIS database: 2023-03-16T14:16:31Z <<<
# 4.请求过程追踪。安装 yum install traceroute。
教程1:https://www.mumupc.com/archives/19402.html
教程2:https://mp.weixin.qq.com/s/ha9LNilrLuA0YIdIonMgVw
[root@localhost ~]# traceroute -m 10 www.bilibili.com
traceroute to www.bilibili.com (221.15.71.67), 10 hops max, 60 byte packets
1 gateway (192.168.3.1) 3.363 ms 4.934 ms 6.603 ms
2 192.168.1.1 (192.168.1.1) 11.931 ms 11.813 ms 11.726 ms
3 10.70.0.1 (10.70.0.1) 11.628 ms 11.539 ms 11.499 ms
4 125.33.184.53 (125.33.184.53) 13.005 ms 11.295 ms 12.848 ms
5 125.33.186.85 (125.33.186.85) 12.922 ms * nec.bta.net.cn (202.96.12.121) 12.680 ms
6 219.158.11.102 (219.158.11.102) 22.875 ms 219.158.108.174 (219.158.108.174) 17.619 ms 219.158.100.94 (219.158.100.94) 15.347 ms
7 pc162.zz.ha.cn (61.168.31.162) 17.776 ms pc98.zz.ha.cn (61.168.30.98) 17.729 ms pc142.zz.ha.cn (61.168.37.142) 16.651 ms
8 hn.kd.ny.adsl (125.45.253.222) 23.836 ms hn.kd.ny.adsl (125.45.253.90) 20.204 ms hn.kd.ny.adsl (125.45.253.222) 23.707 ms
9 hn.kd.dhcp (61.54.92.102) 20.026 ms hn.kd.dhcp (61.54.92.98) 19.822 ms hn.kd.dhcp (61.54.92.102) 19.897 ms
10 * * *
2.报文
2.1.协议的组成
1.请求部分:
GET /App1/1.html HTTP/1.1
Accept: */*
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Host: localhost:8080
Connection: Keep-Alive
username=admin&password=123
请求部分由三部分组成的:
1. 请求行:位于第一行,GET /App1/1.html HTTP/1.1
2. 请求消息头:从第二行开始至第一个空行结束
3. 请求正文:从第一个空行之后的都是正文
2.响应部分:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Accept-Ranges: bytes
ETag: W/"65-1366335797484"
Last-Modified: Fri, 19 Apr 2013 01:43:17 GMT
Content-Type: text/html
Content-Length: 65
Date: Fri, 19 Apr 2013 02:06:23 GMT
Warnning:w1
Warnning: w2
hello http
<a href="b.html">click</a>
<img src="1.jpg"/>
响应部分由三部分组成的:
1. 响应行:位于第一行
2. 响应消息头:从第二行开始至第一个空行结束
3. 响应正文:从第一个空行之后的都是正文
2.2.请求头
HTTP的请求头(Request Headers)包含了关于请求的各种信息,由客户端发送给服务器。这些信息帮助服务器理解客户端的请求,以及如何处理这个请求。
- Host:请求所发送的目标域名或IP地址。
- User-Agent:发送请求的浏览器类型、版本、操作系统等信息。这对于服务器来说很有用,因为它可以根据这些信息来定制响应或识别恶意行为。
- Accept:浏览器能够处理的内容类型,如text/html, image/jpeg等。
- Accept-Language:浏览器所支持的自然语言列表,按照优先级排序。
- Accept-Encoding:浏览器所支持的编码类型,如gzip, deflate等。
- Connection:浏览器是否希望与服务器保持持久连接(如keep-alive)。
- Cookie:包含先前服务器通过Set-Cookie头发送给客户端的cookie信息。
- Referer:发出请求的页面的URL。这通常用于分析来源、防盗链等。
- Cache-Control:指定请求和响应遵循的缓存机制。
- Authorization:包含客户端的认证信息,通常用于HTTP基本认证或Bearer令牌。
- Content-Type:如果请求体中有数据,这个头部会指定数据的类型,如application/json或multipart/form-data。
- Content-Length:请求体的长度(以字节为单位)。
- Origin:发起请求的页面的源(协议、域名和端口)。通常用于CORS(跨源资源共享)检查。
- If-Modified-Since:如果指定的日期之后资源未被修改,则服务器返回304 Not Modified状态,而不返回资源内容。
- If-None-Match:如果资源的ETag没有改变,则服务器返回304 Not Modified状态。
请注意,这只是一个简略的列表,HTTP协议定义了更多的请求头字段,而且也可以自定义请求头字段。在实际应用中,可以根据具体的需求和场景来选择合适的请求头字段。
2.3.cookie
HTTP cookies 详解https://www.w3cschool.cn/pegosu/
http协议是无状态的,但是很多时候需要记录用户的登录状态,所以就出现了cookie。 请求头中包含一个或多个Cookie,用于传递之前服务器通过Set-Cookie响应头发送给客户端的cookie信息。 这样,服务器就能够识别并跟踪特定的用户会话,从而提供个性化的服务或维护用户的登录状态等。
重点:cookie的属性通常都是后端创建的,大部分属性都是作用于浏览器,帮助浏览器控制网站的安全性。
作用:
- 会话管理:例如java后端服务器会生成name=jsessionId
- 个性化服务:基于Cookie存储的用户信息,例如,记录用户偏好设置,调整页面的布局等。
- 用户身份验证:例如使用JWT记录token信息等
- 安全性:可以通过设置Cookie的属性来提高安全性。例如:
- 设置HttpOnly属性,使得Cookie不能通过JavaScript访问,从而防止跨站脚本攻击(XSS)。
- 设置Secure属性,可以确保Cookie只在HTTPS连接中传输,增强数据传输的安全性。
- 网站统计和分析:可以收集用户的访问数据,如访问次数、访问页面等。用于分析用户行为、优化网站结构和内容。
常见的Cookie属性:
- Name(名称):Cookie的名称,用于在服务器端识别和访问特定的Cookie。
- Value(值):Cookie相关联的值,可以是任何字符串或文本。它表示Cookie的具体内容或数据。
- Domain(域):指定了哪些域可以接收该Cookie。只有发送到指定域或其子域的请求才会携带该Cookie。如果未指定,则默认为设置Cookie的同一主机。
- Path(路径):指定了哪些请求URL路径可以访问该Cookie,可以限制Cookie的访问范围,设置为"/"则可以访问全部路径
- Expires/Max-Age(过期时间):设置Cookie的过期时间。
- HttpOnly:设置该属性后,则Cookie只能通过HTTP请求访问,而不能通过客户端脚本(如JavaScript)来访问。 因为攻击者无法使用 JavaScript 窃取或篡改 cookie,这有助于防止跨站脚本攻击(XSS)。
- Secure:当此属性设置为True时,Cookie只能通过HTTPS协议进行传输,而不能在HTTP协议中传输。这增加了Cookie传输的安全性。
- SameSite:用于限制第三方网站访问Cookie(用于告诉浏览器如何处理跨站请求)。作用是防止跨站点请求伪造(CSRF)攻击。 它有三个值:
- Strict:浏览器仅在请求的来源与 cookie 的来源完全匹配时才会附带 cookie。这有助于防止跨站点请求伪造攻击
- Lax:浏览器在某些情况下会附带 cookie,例如,当用户通过链接或按钮从其他站点导航到目标站点时,浏览器会附带 cookie。
- None:不会限制第三方网站访问Cookie,默认值。
如下:设置一条cookie,name是userId, value是123,Path是当前域名下所有的路径,不限制第三方访问cookie,必须使用https,不允许脚本访问。
```http request Set-Cookie: userId=123; Path=/; SameSite=None; Secure; HttpOnly
### 2.4.前端存储
主流方案:
1. Cookie:Cookie的数量和大小都受到一定的限制。通常限制每个域名20个cookie,每个cookie大小4KB
2. Web Storage:2014 年发布的 HTML5 标准新增了 Web Storage 的本地储存方案,其包括 LocalStorage 和 SessionStorage
- LocalStorage 的特点是:
- 使用 Key-Value 形式储存
- 大小有 10MB
- Key 和 Value 以字符串形式储存,不能存储对象
- 使用案例:localStorage.setItem('userId', '123'); localStorage.getItem('userId')
- 区别:SessionStorage 与会话生命周期一致。LocalStorage一直存储在本地。
- IndexedDB:前端数据库,kv结构,可以存储对象,但是操作比较复杂,使用门槛较高。
- GoDB.js。是一个基于 IndexedDB 实现前端本地储存的类库,简化操作,有点类似hibernate是面对对象的使用方式。
## 3.https
[https的连接](https://mp.weixin.qq.com/s/Sqco2jlApWpDAJ9XD7Mgcw)
### 3.1.基础
https 可以认为是 http+TLS,TLS 是传输层加密协议,它的前身是 SSL 协议。
1. http是不安全的:数据容易被拦截,被窃听、被篡改、被冒充等。
2. https是安全的
- 数据加密。连接建立过程使用非对称加密,请求过程报文使用对称加密。公钥公开,私钥在服务端(使用公钥加密,使用私钥解密)
- 身份验证。CA证书,生成签名,
- 数据校验防篡改。
TLS(Transport Layer Security)目前主流的版本主要包括TLS 1.2和TLS 1.3
- 1.2:当前使用最广泛的版本。对安全的要求不高的时候可以使用。
- 1.3:当前最新的版本,使用更强大的加密算法、更好的密钥交换机制和更严格的握手过程。
这使得TLS 1.3在防止中间人攻击、重放攻击和密钥泄露等方面具有更强的防御能力。
### 3.2.CA认证体系
在 CA 认证体系中,所有的证书都是由权威机构来颁发,而权威机构的 CA 证书都是已经在操作系统中内置的,这些证书就是 CA根证书。
CA证书内容:
1. 服务端向权威机构提交公钥和网站基本信息。签发机构 会生成 CA证书 和 私钥。
2. CA证书包括,基础信息、详细信息。
- 基础信息:包括描述信息、有效期、证书和公钥的指纹
- 详细信息:详细的证书数据 和 证书的路径。
如下是百度的证书信息


客户端证书校验过程:这个过程中签名算法RSA:私钥加密,公钥解密(客户端)。
1. 客户端访问服务端时,服务端会将CA证书传给客户端。
2. 客户端使用证书中的路径,找到上级证书(服务器内置)里面的公钥,对证书的指纹进行解密,得到签名(s1)。
3. 客户端根据证书中的内容使用签名算法生成一个新的签名(s2),对比s1和s2,如果不一致,就说明服务端的证书被篡改了。
请求过程(摘要算法起作用):
1. 客户端基于证书,通过 摘要算法 算出 指纹。
2. 发送请求时「指纹 + 明文」一同加密,发送给服务器。
3. 服务器解密后,用相同的摘要算法,算出发送过来的明文,通过比较客户端携带的「指纹」和当前算出的「指纹」做比较,若「指纹」相同,说明数据是完整的。
HTTPS 采用的是对称加密和非对称加密结合的「混合加密」方式:
- 在通信建立前采用非对称加密的方式交换「会话秘钥」,后续就不再使用非对称加密。
- 在通信过程中全部使用对称加密的「会话秘钥」的方式加密明文数据。避免影响请求的处理速度。
使用成本
- 证书费用以及更新维护,证书是按年收费的,每年进行一次续费,并更新为新的证书。
- 降低用户访问速度
- 消耗 CPU 资源,需要增加大量机器
### 3.3.TLS四次握手
SSL/TLS 协议基本流程:前两步就是TLS四次握手的步骤。
- 客户端向服务器索要并验证服务器的公钥。
- 双方协商生成会话秘钥
- 双方采用会话秘钥进行加密通信。
TLS握手与TCP握手的关系
1. TLS 1.2:HTTPS 是先进行 TCP 三次握手,再进行 TLSv1.2 四次握手
2. TLS 1.3:客户端和服务端都开启了 TCP Fast Open 功能,TLS 和 TCP同时开启。
详细过程:
1. 客户端 发起加密通信请求,也就是 ClientHello 请求,该请求中包括的内容:
- 客户端支持的 SSL/TLS 协议版本,如 TLS 1.2 版本。
- 客户端生成的随机数( Client Random ),后面用于生成 会话秘钥。
- 客户端支持的密码套件列表,如 RSA 加密算法。
2. 服务端响应 SeverHello请求。响应的内容包括
- 确认 SSL/ TLS 协议版本,如果浏览器不支持,则关闭加密通信。
- 服务器生成的随机数( Server Random ),后面用于生成 会话秘钥。
- 确认的密码套件列表,如 RSA 加密算法。
- 服务器的数字证书。
3. 客户端,验证证书的真实性。没有问题的话,就从证书中拿到公钥,加密以下信息发送给服务端
- 一个随机数( pre-master key )。该随机数会被服务器公钥加密。
- 加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信。
- 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时把之前所有内容的发生的数 据做个摘要,用来供服务端校验。
4. 服务器收到客户端的第三个随机数( pre-master key )之后,通过协商的加密算法,计算出本次通信的 「会话秘钥」。然后向客户端发送最后的信息:
- 加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信。
- 服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供客户端校验。
三个随机数的作用:为了安全,防止秘钥被泄露。
1. client_random和server_random是明文的,它们分别由客户端和服务器生成,并直接用于后续的秘钥生成过程。
2. pre_master是被加密的随机数,由客户端生成并使用服务器的公钥进行加密,然后发送给服务器。
3. 在服务器解密后,与client_random和server_random一起用于生成最终的会话秘钥。
### 3.4.对性能的影响
TCP进过三次握手之后,就可以直接进行数据交互,来回只需要一个RTT。协议交互所增加的网络 RTT (Round-Trip Time, 往返时延),
这也是影响我们网络访问速度的一个重要因素。

HTTPS 相比 HTTP 有可能增加 7 个 RTT
1. 【可优化】三次握手建立 TCP 连接,耗时 1 个 RTT。
2. 【可优化】HTTP 使用一个 GET 请求,服务端返回一个 302 跳转到 https, 这里需要 1 个 RTT 的往返时延和 302 的跳转延迟,
因为大部分情况下用户不会直接输入 https:// 域名而只会直接输入域名。所以服务端只会返回 302 强制浏览器跳转到 https,而浏览器处理 302 的跳转本身也需要耗时。
3. 浏览器跳转到 https 的连接,由于端口不同,需要重新完成 TCP 的三次握手,重新建立 TCP 连接。
4. TLS 完全握手阶段 1,这里需要耗时 1 个 RTT, 这个阶段主要是完成加密套件的协商和证书的身份确认。
这个阶段下,服务端和浏览器会协商出相同的密钥交换算法,对称加密算法,内容一致性校验算法,证书签名算法等等。浏览器获取到证书后也需要校验证书的有效性,比如证书是否过期,是否撤销等等。
5. 浏览器首先获取证书中的 CA 域名,如果这个 CA 域名没有命中缓存的话,浏览器需要解析 CA 域名的 DNS, 这个 DNS 的解析需要耗费 1 个 RTT。
6. 从 CA 域名解析的 IP 地址,需要建立 3 次握手,建立 CA 站点的 TCP 连接,这里耗时 1 个 RTT.
7. 浏览器发送 ocsp (Online Certificate Status Protocol, 在线状态证书协议,维护服务器和其他网络资源安全性的两种普遍模式之一。
另外一个叫做 CRL,证书注销列表) 请求,获取响应,耗时 1 个 RTT. 用户会向 CA 服务器发送一个关于证书状态信息的请求,
服务器会回复给用户一个 "有效","过期" 或者 "未知" 的响应,协议规定了服务器和客户端应用程序的一个通信语法,
在线状态证书协议给了用户到期证书一个宽限期,这样他们就可以在更新以前的一段时间,继续访问到服务器,所以这里就需要发起一个对证书状态信息的请求,也需要消耗一个 RTT。
8. TLS 完全握手阶段 2,这个阶段进行的是密钥协商,耗时 1 个 RTT 和计算时间,这个阶段完成后,浏览器和服务器才进行 HTTP 应用层的数据传输,跟 HTTP 协议是相同的。
### 3.2.HTTPS双向认证指南
HTTPS双向认证(Mutual TLS,mTLS)是一种增强型安全协议,在一些安全级别较高的场景非常有用,要求客户端和服务器均验证对方的数字证书,确保双方身份可信
准备:
1. 根证书(CA Certificate):由可信证书颁发机构(CA)签发,或自建私有CA。
2. 服务器证书:由CA签发,包含服务器域名/IP,私钥由服务器保管。
3. 客户端证书:由CA签发,包含客户端标识(如用户ID),私钥由客户端保管。
适用场景
1. 企业内网服务:API网关验证客户端设备合法性。
2. IoT设备通信:确保设备与云端双向可信。
3. 金融交易系统:支付接口要求客户端(商户)强身份认证。
4. 零信任架构:替代传统VPN,基于证书的动态访问控制。
TLS握手过程
```text
sequenceDiagram
participant Client
participant Server
Client->>Server: ClientHello(支持加密套件列表)
Server->>Client: ServerHello(选定加密套件)+ 服务器证书
Note over Client: 验证服务器证书有效性
Client->>Server: 客户端证书(需双向认证时)
Note over Server: 验证客户端证书有效性
Server->>Client: CertificateRequest(请求客户端证书)
Client->>Server: CertificateVerify(签名验证)
Server->>Client: ServerHelloDone
Client->>Server: 生成会话密钥(Pre-Master Secret)
Server->>Client: 确认密钥交换完成
Note over Client,Server: 开始加密通信
应用案例
服务端:nginx
server {
listen 443 ssl;
server_name api.example.com;
# 服务器证书及私钥
ssl_certificate /path/to/server.crt;
ssl_certificate_key /path/to/server.key;
# 客户端证书验证【服务端存储客户端的证书】
ssl_client_certificate /path/to/ca.crt; # 信任的CA证书
ssl_verify_client on; # 强制要求客户端证书
ssl_verify_depth 2; # 证书链深度
# 其他SSL参数
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256;
}
客户端:发送请求时,需要携带客户端的证书公钥
curl --cert client.crt --key client.key --cacert ca.crt https://api.example.com
4.QUIC特性
http3的特性其实就是QUIC特性
4.1.RTT建立连接
RTT: round-trip time, 仅包括请求访问来回的时间。http 1.1 建立连接的时候,需要3次握手,也就是3个RTT。
HTTP/3首次连接只需要1RTT, 后面的链接只需要0RTT, 意味着客户端发送给服务端的第一个包就带有请求数据, 其主要连接过程如下:
- 首次连接, 客户端发送Inchoate Client Hello, 用于请求连接;
- 服务端生成g, p, a, 根据g, p, a算出A, 然后将g, p, A放到Server Config中在发送Rejection消息给客户端.
- 客户端接收到g,p,A后, 自己再生成b, 根据g,p,a算出B, 根据A,p,b算出初始密钥K, B和K算好后, 客户端会用K加密HTTP数据, 连同B一起发送给服务端.
- 服务端接收到B后, 根据a,p,B生成与客户端同样的密钥, 再用这密钥解密收到的HTTP数据. 为了进一步的安全(前向安全性), 服务端会更新自己的随机数a和公钥, 在生成新的密钥S, 然后把公钥通过Server Hello发送给客户端. 连同Server Hello消息, 还有HTTP返回数据.

这里使用DH密钥交换算法, DH算法的核心就是服务端生成a,g,p3个随机数, a自己持有, g和p要传输给客户端, 而客户端会生成b这1个随机数, 通过DH算法客户端和服务端可以算出同样的密钥. 在这过程中a和b并不参与网络传输, 安全性大大提升. 因为p和g是大数, 所以即使在网络传输中p, g, A, B都被劫持, 靠现在的计算力算力也无法破解.
4.2.连接迁移
TCP连接基于四元组(源IP, 源端口, 目的IP, 目的端口), 切换网络时至少会有一个因素发生变化, 导致连接发送变化. 当连接发送变化是, 如果还是用原来的TCP连接, 则会导致连接失败, 就得等到原来的连接超时后重新建立连接, 所以我们有时候发现切换到一个新的网络时, 即使网络状况良好, 但是内容还是需要加载很久. 如果实现的好, 当检测到网络变化时, 立即建立新的TCP连接, 即使这样, 建立新的连接还是需要几百毫秒时间.
QUIC不受四元组的影响, 当这四个元素发生变化时, 原连接依然维持. 原理如下:
QUIC不以四元素作为表示, 而是使用一个64位的随机数, 这个随机数被称为Connection ID, 即使IP或者端口发生变化, 只要Connection ID没有变化, 那么连接依然可以维持.
4.3.队头阻塞/多路复用
HTTP/1.1和HTTP/2都存在队头阻塞的问题(Head Of Line blocking). TCP是个面向连接的协议, 即发送请求后需要收到ACK消息, 以确认对象已接受数据. 如果每次请求都要在收到上次请求的ACK消息后再请求, 那么效率无疑很低. 后来HTTP/1.1提出了Pipeline技术, 允许一个TCP连接同时发送多个请求. 这样就提升了传输效率.
队头阻塞:一个TCP连接同时传输10个请求, 其中1,2,3个请求给客户端接收, 但是第四个请求丢失, 那么后面第5-10个请求都被阻塞. 需要等第四个请求处理完毕后才能被处理. 这样就浪费了带宽资源. 因此, HTTP一般又允许每个主机建立6个TCP连接, 这样可以更加充分的利用带宽资源, 但每个连接中队头阻塞的问题还是存在的.
HTTP/2的多路复用解决了上述的队头阻塞问题. 在HTTP/2中, 每个请求都被拆分为多个Frame通过一条TCP连接同时被传输, 这样即使一个请求被阻塞, 也不会影响其他的请求 但是, HTTP/2虽然可以解决请求这一粒度下的阻塞, 但HTTP/2的基础TCP协议本身却也存在队头阻塞的问题. HTTP/2的每个请求都会被拆分成多个Frame, 不同请求的Frame组合成Stream, Stream是TCP上的逻辑传输单元, 这样HTTP/2就达到了一条连接同时发送多个请求的目标, 其中Stram1已经正确送达, Stram2中的第三个Frame丢失 TCP处理数据是有严格的前后顺序, 先发送的Frame要先被处理, 这样就会要求发送方重新发送第三个Frame, Steam3和Steam4虽然已到达但却不能被处理, 那么这时整条链路都会被阻塞.
QUIC是如何解决队头阻塞的问题的? 主要有两点:
- QUIC的传输单位是Packet, 加密单元也是Packet, 整个加密, 传输, 解密都基于Packet, 这就能避免TLS的阻塞问题.
- QUIC基于UDP, UDP的数据包在接收端没有处理顺序, 即使中间丢失一个包, 也不会阻塞整条连接. 其他的资源会被正常处理.
4.4.拥塞控制
拥塞控制的目的是避免过多的数据一下子涌入网络, 导致网络超出最大负荷. QUIC的拥塞控制与TCP类似, 并在此基础上做了改进. 先来看看TCP的拥塞控制.
- 慢启动: 发送方像接收方发送一个单位的数据, 收到确认后发送2个单位, 然后是4个, 8个依次指数增长, 这个过程中不断试探网络的拥塞程度.
- 避免拥塞: 指数增长到某个限制之后, 指数增长变为线性增长
- 快速重传: 发送方每一次发送都会设置一个超时计时器, 超时后认为丢失, 需要重发
- 快速恢复: 在上面快速重传的基础上, 发送方重新发送数据时, 也会启动一个超时定时器, 如果收到确认消息则进入拥塞避免阶段, 如果仍然超时, 则回到慢启动阶段.
QUIC重新实现了TCP协议中的Cubic算法进行拥塞控制, 下面是QUIC改进的拥塞控制的特性:
- 热插拔。tcp的拥塞算法调整需要修改内核参数,这样会导致整个服务器的配置都发生变化。而QUIC的调整是应用侧的配置调整。
- 前向纠错 FEC。
- 单调递增的Packer Number。TCP为了保证可靠性使用Sequence Number和ACK来确认消息是否有序到达
- ACK Delay。
- 更多的ACK块
5.常见面试题
浏览器与服务器建立TCP连接后,是否会在一个http请求完成后断开?什么情况下回断开?
http/1.0 的时候,服务器完成一个http连接之后就会断开这个连接,每次请求每次重连。 到了http/1.1 后 ,增加了 Connection: keep-alive,在请求之后会保持连接一定时间。 当 Header 中有 collection: close 的时候,TCP连接会关闭; 或者 当keep-alive 设置的时间到了,自动断开。
一个 TCP 连接可以对应几个http请求?
一个 TCP 是全双工通讯的,创建出来后,会保持一定时间。这个时间内,可以发送多个http请求,并且可以同时发送多个请求。
一个 TCP 连接中,多个http请求可以同时一起发送吗?
在http/1.1 中, 单个 TCP 同时只能处理一个请求。当打开浏览器的时候,同时发送多个请求,他们应该各个会创建一个 TCP 连接。 其实就是两个不同的http请求,开始到结束的时间在同一个 TCP 连接里不能重叠。但是在http/2, 提供了multiplexing,支持多路传输
虽然1.1中增加了channel特性,支持同时发送多个请求,但是浏览器并没有支持这个特性。
为什么有的时候刷新页面不需要重新创建SSL连接?
TCP 连接有的时候会被浏览器和服务端维持一段时间,SSL是作用于TCP之上的,TCP 不需要重新建立,SSL也就不用。
浏览器对同一个host建立的TCP连接数量是否有限制?
假设我们还处在 HTTP/1.1 时代,那个时候没有多路传输,当浏览器拿到一个有几十张图片的网页该怎么办呢? 肯定不能只开一个 TCP 连接顺序下载,那样用户肯定等的很难受但是如果每个图片都开一个 TCP 连接发 HTTP 请求, 那电脑或者服务器都可能受不了要是有 1000 张图片的话总不能开 1000 个TCP 连接吧,你的电脑同意 NAT 也不一定会同意。 Chrome 最多允许对同一个 Host 建立六个 TCP 连接。不同的浏览器有一些区别。
HTTP长连接、短连接究竟是什么?
https://www.cnblogs.com/gotodsp/p/6366163.html
总结:短连接简单,没有任何维护成本,随用随开,用完就关。而长连接,可以降低开关连接的开销,提升一定程度的性能,但是需要维护保持连接的相关逻辑。
- 本文作者:zhangxue
- 本文链接:https://lucksnow1989.github.io/article/4.网络&通讯协议/3.http.html
- 版权声明:本文为本人原创文章,遵循 CC 4.0 BY-NC-SA版权协议,转载请附上原文出处链接和本声明。