网络抓包-TCP

基础

TCP 的完整生命周期可以划分为 三个核心阶段:建立连接(三次握手) → 传输数据(可靠传输与流量/拥塞控制) → 断开连接(四次挥手)。

流程总览:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
客户端 (Client)                               服务端 (Server)
| |
| ------------- 1. SYN (Seq=x) --------------> | (LISTEN)
| <------- 2. SYN+ACK (Seq=y, Ack=x+1) ------- | (SYN-RCVD)
| ------------- 3. ACK (Ack=y+1) ------------> | (ESTABLISHED)
| |
|============ 建立连接 (三次握手) ============|
| |
| -------------- 数据包 (Seq=x+1) -----------> | (接收数据)
| <------------- ACK包 (Ack=x+n) ------------- | (确认收到)
| |
|============ 数据传输 (滑动窗口/重传) =======|
| |
| ------------- 1. FIN (Seq=u) --------------> | (CLOSE-WAIT)
| <------------- 2. ACK (Ack=u+1) ------------ |
| <------------- 3. FIN (Seq=v) -------------- | (LAST-ACK)
| ------------- 4. ACK (Ack=v+1) ------------> | (CLOSED)
| (TIME-WAIT 2MSL) |
| (CLOSED) |
| |
|============ 断开连接 (四次挥手) ============|

  1. 阶段 1:连接建立 —— 三次握手(Three-Way Handshake)
    • 目的: 确认双方的接收与发送能力均正常,同步双方的初始序列号(ISN, Initial Sequence Number),并协商 MSS(最大报文段长度)等参数。

    • 1 第一次握手:SYN(客户端 → 服务端)

      • 具体动作: 客户端向服务端发送 SYN=1 的报文,随机生成一个初始序列号 Seq = x。此时客户端进入 SYN-SENT 状态。
      • 作用: 告诉服务端:“我想建立连接,我的初始序列号是 x”。
    • 2 第二次握手:SYN + ACK(服务端 → 客户端)

      • 具体动作: 服务端收到 SYN 后,回复 SYN=1, ACK=1 报文,确认号 Ack = x + 1,同时自己也随机生成一个初始序列号 Seq = y。此时服务端进入 SYN-RCVD 状态。
      • 作用: 告诉客户端:“收到你的请求了,我同意建立连接,我的初始序列号是 y”。
    • 3 第三次握手:ACK(客户端 → 服务端)

      • 具体动作: 客户端收到服务端的响应后,发送 ACK=1 报文,确认号 Ack = y + 1,自身的序列号变为 Seq = x + 1。此时客户端进入 ESTABLISHED 状态,服务端收到后也进入 ESTABLISHED 状态。
      • 作用: 告诉服务端:“收到你的同意了,连接正式建立!”(此时第三次握手可以携带客户端要发送的数据)。
  2. 数据传输 —— 可靠机制与控制(Data Transfer)
    • 连接建立后,双方开始互传数据。TCP 通过以下机制保障“数据不丢失、不重复、按序到达、不冲垮对方和网络”:
    • 按序到达与去重(Seq / Ack 机制):
      • 每个传输的数据包都带有 Sequence Number(序列号),接收方收到后回复 Acknowledgment Number(确认号),告知发送方下一个期待接收的字节序号。如果收到重复包则直接丢弃。
    • 超时重传与快速重传(Retransmission):
      • 超时重传(RTO): 发送方发包后开启计时器,若超过一定时间未接收到 ACK,即判定丢包并重新发送。
      • 快速重传(Fast Retransmissions): 接收方连续收到 3 个相同的冗余 ACK(Dup ACK),发送方无需等待超时定时器,立即重传丢失的数据包。
    • 流量控制(Flow Control - 滑动窗口):
      • 接收方在 ACK 包中通过 Window Size(窗口大小) 字段实时告知发送方自己当前的接收缓冲区剩余空间,防止发送方发得太快导致接收方缓冲区溢出而丢包。
    • 拥塞控制(Congestion Control):
      • 避免过多数据注入网络导致路由器或链路过载。主要由四大算法控制:慢启动(Slow Start)、拥塞避免(Congestion Avoidance)、快速重传(Fast Retransmit) 和 快速恢复(Fast Recovery)。动态调整拥塞窗口(cwnd)。
  3. 连接断开 —— 四次挥手(Four-Way Teardown)
    • 目的: 全双工连接的双方分别关闭自己的发送通道,优雅地终止通信。因为 TCP 是全双工的(双向都可以独立传输数据),所以每个方向都需要单独关闭。

    • 第一次挥手:FIN(主动方 → 被动方)

      • 具体动作: 主动方(如客户端)发送 FIN=1, Seq = u 报文,进入 FIN-WAIT-1 状态。
      • 作用: 告诉对方:“我没有数据要发送了,但我还可以接收数据”。
    • 第二次挥手:ACK(被动方 → 主动方)

      • 具体动作: 被动方收到后回复 ACK=1, Ack = u + 1 报文,进入 CLOSE-WAIT 状态;主动方收到后进入 FIN-WAIT-2 状态。
      • 作用: 告诉主动方:“收到你的断开请求了,但我可能还有没发完的数据,等我处理完”。
    • 第三次挥手:FIN(被动方 → 主动方)

      • 具体动作: 被动方将剩余数据发送完毕后,发送 FIN=1, ACK=1, Seq = v, Ack = u + 1 报文,进入 LAST-ACK 状态。
      • 作用: 告诉主动方:“我的数据也发完了,可以正式关闭连接了”。
    • 第四次挥手:ACK(主动方 → 被动方)

      • 具体动作: 主动方回复 ACK=1, Ack = v + 1 报文,进入 TIME-WAIT 状态。被动方收到后直接进入 CLOSED 状态。主动方在等待 2MSL(最大报文生存时间)后也进入 CLOSED 状态。
      • 作用: 确认被动方的断开请求。

抓包

1
2
3
7      0.022088400      192.168.0.12      223.109.82.212      TCP      66      2993 → 443 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM
8 0.037079300 223.109.82.212 192.168.0.12 TCP 66 443 → 2993 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1400 WS=32 SACK_PERM
9 0.037355900 192.168.0.12 223.109.82.212 TCP 54 2993 → 443 [ACK] Seq=1 Ack=1 Win=263168 Len=0
  • TCP 三次握手(连接建立): No. 7 - 9.
  • 数据包 7 到 9 展示了完整的建立过程:
  • No. 7:客户端 192.168.0.12:2993 发送 [SYN](Seq=0)。
  • No. 8:服务端 223.109.82.212:443 回复 [SYN, ACK](Seq=0, Ack=1)。
  • No. 9:客户端回复 [ACK](Seq=1, Ack=1),TCP 连接成功建立。
  • 验证成功: 第 9 包后,双方 TCP 状态均变为 ESTABLISHED。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
10      0.038365100      192.168.0.12      223.109.82.212      TCP      1454      2993 → 443 [ACK] Seq=1 Ack=1 Win=263168 Len=1400 [TCP PDU reassembled in 11]
11 0.038365100 192.168.0.12 223.109.82.212 TLSv1.2 385 Client Hello (SNI=www.baidu.com)
12 0.064204800 223.109.82.212 192.168.0.12 TCP 60 443 → 2993 [ACK] Seq=1 Ack=1732 Win=82304 Len=0
13 0.066597000 223.109.82.212 192.168.0.12 TLSv1.2 1454 Server Hello
14 0.066597000 223.109.82.212 192.168.0.12 TCP 1454 443 → 2993 [ACK] Seq=1401 Ack=1732 Win=82304 Len=1400 [TCP PDU reassembled in 17]
15 0.066878700 192.168.0.12 223.109.82.212 TCP 54 2993 → 443 [ACK] Seq=1732 Ack=2801 Win=263168 Len=0
16 0.067020200 223.109.82.212 192.168.0.12 TCP 1454 443 → 2993 [ACK] Seq=2801 Ack=1732 Win=82304 Len=1400 [TCP PDU reassembled in 17]
17 0.067020200 223.109.82.212 192.168.0.12 TLSv1.2 1060 Certificate, Server Key Exchange, Server Hello Done
18 0.067080300 192.168.0.12 223.109.82.212 TCP 54 2993 → 443 [ACK] Seq=1732 Ack=5207 Win=263168 Len=0
19 0.070535400 192.168.0.12 223.109.82.212 TLSv1.2 180 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
20 0.071346100 192.168.0.12 223.109.82.212 TLSv1.2 801 Application Data
21 0.080248200 223.109.82.212 192.168.0.12 TCP 1060 [TCP Spurious Retransmission] 443 → 2993 [PSH, ACK] Seq=4201 Ack=1732 Win=82304 Len=1006
22 0.080493500 192.168.0.12 223.109.82.212 TCP 66 [TCP Dup ACK 18#1] 2993 → 443 [ACK] Seq=2605 Ack=5207 Win=263168 Len=0 SLE=4201 SRE=5207
23 0.090828300 223.109.82.212 192.168.0.12 TCP 60 443 → 2993 [ACK] Seq=5207 Ack=1858 Win=82304 Len=0
24 0.091006000 223.109.82.212 192.168.0.12 TLSv1.2 280 New Session Ticket, Change Cipher Spec, Encrypted Handshake Message
  • TLS 1.2 加密协商: No. 10 - 24.
  • 在 TCP 之上建立 HTTPS 安全通道:
  • No. 11:客户端发送 Client Hello(请求访问 [www.baidu.com](https://www.baidu.com))。
  • No. 13-17:服务端回复 Server Hello、证书(Certificate)及密钥交换数据。
  • No. 19:客户端发送密钥交换(Client Key Exchange)及 Change Cipher Spec。
  • No. 24:服务端完成密钥协商,加密通道准备就绪。
  • 验证成功:* 第 24 包后,后续传输全部转为 Application Data 密文。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
25      0.091889000      223.109.82.212      192.168.0.12      TCP      60      443 → 2993 [ACK] Seq=5433 Ack=2605 Win=85120 Len=0
26 0.094859900 223.109.82.212 192.168.0.12 TLSv1.2 1262 Application Data
27 0.095098300 192.168.0.12 223.109.82.212 TCP 54 2993 → 443 [ACK] Seq=2605 Ack=6641 Win=263168 Len=0
28 0.095234600 223.109.82.212 192.168.0.12 TCP 1454 443 → 2993 [ACK] Seq=6641 Ack=2605 Win=85120 Len=1400 [TCP PDU reassembled in 29]
29 0.095234600 223.109.82.212 192.168.0.12 TLSv1.2 1454 Application Data
30 0.095234600 223.109.82.212 192.168.0.12 TLSv1.2 1454 Application Data, Application Data, Application Data
31 0.095234600 223.109.82.212 192.168.0.12 TCP 1454 443 → 2993 [ACK] Seq=10841 Ack=2605 Win=85120 Len=1400 [TCP PDU reassembled in 32]
32 0.095234600 223.109.82.212 192.168.0.12 TLSv1.2 957 Application Data, Application Data
33 0.095413600 192.168.0.12 223.109.82.212 TCP 54 2993 → 443 [ACK] Seq=2605 Ack=13144 Win=263168 Len=0
34 0.113460200 223.109.82.212 192.168.0.12 TCP 957 [TCP Spurious Retransmission] 443 → 2993 [PSH, ACK] Seq=12241 Ack=2605 Win=85120 Len=903
35 0.113663100 192.168.0.12 223.109.82.212 TCP 66 [TCP Dup ACK 33#1] 2993 → 443 [ACK] Seq=2605 Ack=13144 Win=263168 Len=0 SLE=12241 SRE=13144
36 0.364462700 192.168.0.12 223.109.82.212 TLSv1.2 861 Application Data
37 0.384911800 223.109.82.212 192.168.0.12 TCP 60 443 → 2993 [ACK] Seq=13144 Ack=3412 Win=87936 Len=0
38 0.440156400 223.109.82.212 192.168.0.12 TCP 1454 443 → 2993 [ACK] Seq=13144 Ack=3412 Win=87936 Len=1400 [TCP PDU reassembled in 40]
39 0.440156400 223.109.82.212 192.168.0.12 TCP 1454 443 → 2993 [ACK] Seq=14544 Ack=3412 Win=87936 Len=1400 [TCP PDU reassembled in 40]
40 0.440156400 223.109.82.212 192.168.0.12 TLSv1.2 1379 Application Data
41 0.440156400 223.109.82.212 192.168.0.12 TLSv1.2 1454 Application Data
42 0.440156400 223.109.82.212 192.168.0.12 TCP 1454 443 → 2993 [ACK] Seq=18669 Ack=3412 Win=87936 Len=1400 [TCP PDU reassembled in 49]
43 0.440442600 192.168.0.12 223.109.82.212 TCP 54 2993 → 443 [ACK] Seq=3412 Ack=20069 Win=263168 Len=0
44 0.440573400 223.109.82.212 192.168.0.12 TCP 1454 443 → 2993 [ACK] Seq=20069 Ack=3412 Win=87936 Len=1400 [TCP PDU reassembled in 49]
45 0.440573400 223.109.82.212 192.168.0.12 TCP 1454 443 → 2993 [ACK] Seq=21469 Ack=3412 Win=87936 Len=1400 [TCP PDU reassembled in 49]
46 0.440573400 223.109.82.212 192.168.0.12 TCP 1454 443 → 2993 [ACK] Seq=22869 Ack=3412 Win=87936 Len=1400 [TCP PDU reassembled in 49]
47 0.440573400 223.109.82.212 192.168.0.12 TCP 1454 443 → 2993 [ACK] Seq=24269 Ack=3412 Win=87936 Len=1400 [TCP PDU reassembled in 49]
48 0.440573400 223.109.82.212 192.168.0.12 TCP 1454 443 → 2993 [ACK] Seq=25669 Ack=3412 Win=87936 Len=1400 [TCP PDU reassembled in 49]
49 0.440573400 223.109.82.212 192.168.0.12 TLSv1.2 1373 Application Data, Application Data
50 0.440689800 192.168.0.12 223.109.82.212 TCP 54 2993 → 443 [ACK] Seq=3412 Ack=28388 Win=263168 Len=0
108 0.692460400 192.168.0.12 223.109.82.212 TLSv1.2 895 Application Data
109 0.712951200 223.109.82.212 192.168.0.12 TCP 60 443 → 2993 [ACK] Seq=28388 Ack=4253 Win=90880 Len=0
124 0.769525600 223.109.82.212 192.168.0.12 TCP 1454 443 → 2993 [ACK] Seq=28388 Ack=4253 Win=90880 Len=1400 [TCP PDU reassembled in 125]
125 0.769525600 223.109.82.212 192.168.0.12 TLSv1.2 925 Application Data
126 0.769665400 192.168.0.12 223.109.82.212 TCP 54 2993 → 443 [ACK] Seq=4253 Ack=30659 Win=263168 Len=0
  • 数据交互(HTTP 请求与响应): No. 20 - 126.
  • 网页数据的双向传输:
  • 客户端发送加密请求(如 No. 20, 36, 108)。
  • 服务端分段返回大量网页资源数据(如 No. 28-32, 40-49, 125)。
  • 期间触发了 TCP 选段重传与 SACK 确认(如 No. 21-22, 34-35),反映了真实的动态网络抖动。
1
2
329      15.806560000      223.109.82.212      192.168.0.12      TCP      60      [TCP Keep-Alive] 443 → 2993 [ACK] Seq=30658 Ack=4253 Win=90880 Len=0
330 15.806634000 192.168.0.12 223.109.82.212 TCP 54 [TCP Keep-Alive ACK] 2993 → 443 [ACK] Seq=4253 Ack=30659 Win=263168 Len=0
  • TCP Keep-Alive 保活探测: No. 329 - 330.
  • 数据传输完成后,连接进入空闲状态:
  • No. 329(约第 15.8 秒):服务端向客户端发送 [TCP Keep-Alive] 询问连接是否有效。
  • No. 330:客户端网络栈立即响应 [TCP Keep-Alive ACK] 确认在线。
1
2
3
4
5
347      22.117811800      192.168.0.12      223.109.82.212      TCP      54      2993 → 443 [FIN, ACK] Seq=4253 Ack=30659 Win=263168 Len=0
350 22.138313900 223.109.82.212 192.168.0.12 TCP 60 443 → 2993 [ACK] Seq=30659 Ack=4254 Win=90880 Len=0
351 22.138313900 223.109.82.212 192.168.0.12 TLSv1.2 85 Encrypted Alert
352 22.138313900 223.109.82.212 192.168.0.12 TCP 60 443 → 2993 [FIN, ACK] Seq=30690 Ack=4254 Win=90880 Len=0
353 22.138876300 192.168.0.12 223.109.82.212 TCP 54 2993 → 443 [RST, ACK] Seq=4254 Ack=30690 Win=0 Len=0

TCP 四次挥手与关闭(连接终止): No. 347 - 353. 主动关闭标签页或离线后,触发的完整断开流程:

  1. No. 347(第一次挥手):客户端主动发起断开,发送 [FIN, ACK](Seq=4253, Ack=30659)。
  2. No. 350(第二次挥手):服务端回复 [ACK](Ack=4254),确认收到客户端的关闭请求。
  3. No. 351-352(第三次挥手):服务端发送 TLS 告警通知关闭后,随即发送 [FIN, ACK](Seq=30690, Ack=4254),表示服务端也准备关闭。
  4. No. 353(最终重置/关闭):客户端收到服务端的 FIN 后,由于本地套接字已彻底关闭,回复 [RST, ACK],将连接直接重置并强制释放资源。

验证成功: 双方彻底清理端口资源,TCP 连接生命周期结束。

总结

  1. Seq(Sequence Number):我这次发给你的数据,从第几字节开始。

  2. Ack(Acknowledgment Number):你等会发给我的数据,应该从第几字节开始(代表我在这之前的字节都已经收齐了)。

  3. 重传

    • 首先 ACK 表示 这个序号之前的数据已经收齐了
    • ACK = 1001 连续收到的数据只到 1000 告诉对面从1001开始发送数据过来
    • SACK Option 记录着 ACK 后面收到的 不连续数据
    • SACK Option = [4001 ~ 6001], [2001 ~ 3001]
    • 第一块:4001 到 6000
    • 第二块:2001 到 3000
    • 客户端:“百度,我最远只收到了第 1000 字节,你等会儿发送给我的数据请从 1001 开始(ACK=1001);但是你先别急着把 1001 后面的全部重发,因为 2001~3000 和 4001~6000 这两段我已经拿到了,你只把中间空着的那两块给补上就行(SACK 区间)!”

  4. 只有建立连接(SYN)、断开连接(FIN)和真实传输数据(Len > 0)才会让 Seq 增加;纯控制包(如纯 ACK、RST)的 Seq 永远保持不动。

  5. 数据包Len长度 = 抓包软件Length - 数据链路层 14 字节 - 网络层 20 字节 - 传输层 20 字节

  6. 抓包软件Length = 以太网头部 (14B) + IP 头部 (20B) + TCP 头部 (20B) + 实际数据 (331B) = 385B

    • 如果 TCP Header 带有 Options(比如握手时的 MSS、WS 或传输时的 SACK 自身),TCP 头部会大于 20 字节。
  7. ws是窗口缩放因子,握手1 我告诉对面 我的ws,握手2 对面告诉我他的ws (只有ws相对传递完毕,就是握手3才开始生效,之前都为1)

  8. 真正的窗口大小要看数据包具体字段Window: 2572, 抓包工具只会显示 *ws后的数值

  9. 字段Window 只有16位 上限64KB 需要WS辅助

  10. 软件显示的ws 256 非传输的值。TCP Option - Window scale: 8 (multiply by 256) 实际发送的是8给对面,对面会通过2^8=256得出我这边的ws

  11. TCP PDU reassembled in 11 软件里有这个表示数据包太大,被切分了。数值11 表示最后一个包是在No.11

1
2
3
4
5
6
7
8
9
10
10      0.038365100      192.168.0.12      223.109.82.212      TCP      1454      2993 → 443 [ACK] Seq=1 Ack=1 Win=263168 Len=1400 [TCP PDU reassembled in 11]
11 0.038365100 192.168.0.12 223.109.82.212 TLSv1.2 385 Client Hello (SNI=www.baidu.com)

14 0.066597000 223.109.82.212 192.168.0.12 TCP 1454 443 → 2993 [ACK] Seq=1401 Ack=1732 Win=82304 Len=1400 [TCP PDU reassembled in 17]
16 0.067020200 223.109.82.212 192.168.0.12 TCP 1454 443 → 2993 [ACK] Seq=2801 Ack=1732 Win=82304 Len=1400 [TCP PDU reassembled in 17]
17 0.067020200 223.109.82.212 192.168.0.12 TLSv1.2 1060 Certificate, Server Key Exchange, Server Hello Done

#上面是分包了 下面是未分包
12 0.064204800 223.109.82.212 192.168.0.12 TCP 60 443 → 2993 [ACK] Seq=1 Ack=1732 Win=82304 Len=0
13 0.066597000 223.109.82.212 192.168.0.12 TLSv1.2 1454 Server Hello

tls

Handshake Type: Server Hello (2) 里的 Version: TLS 1.2 (0x0303) 才会最后确定使用的tls 版本。不要被TLSv1.2 Record Layer: Handshake Protocol: Server Hello误导

1
2
10      0.038365100      192.168.0.12      223.109.82.212      TCP      1454      2993 → 443 [ACK] Seq=1 Ack=1 Win=263168 Len=1400 [TCP PDU reassembled in 11]
11 0.038365100 192.168.0.12 223.109.82.212 TLSv1.2 385 Client Hello (SNI=www.baidu.com)
  1. 代码/类型:Client Hello (SNI=[www.baidu.com](https://www.baidu.com))
  2. 正在做什么:你的电脑(192.168.0.12)向百度服务器发起 TLS 加密申请。
  3. 告知 SNI:明确指定要访问的域名是 [www.baidu.com](https://www.baidu.com)。
  4. 提交算法清单:把你电脑支持的加密算法组合(Cipher Suites)、TLS 版本列表发给服务器供其挑选。
  5. 发送 Client Random:发送客户端生成的随机数 A(后续用来计算对称密钥)。
  6. 里面也包含支持哪些tls版本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Client Hello
Handshake Protocol: Client Hello
Random: 2a1c5...f3455152786189e22
Extension: supported_versions (len=7) TLS 1.3, TLS 1.2
Cipher Suites (16 suites)
Cipher Suite: Reserved (GREASE) (0x2a2a)
Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301)
Cipher Suite: TLS_AES_256_GCM_SHA384 (0x1302)
Cipher Suite: TLS_CHACHA20_POLY1305_SHA256 (0x1303)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)
Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)

0

1
2
12      0.064204800      223.109.82.212      192.168.0.12      TCP      60      443 → 2993 [ACK] Seq=1 Ack=1732 Win=82304 Len=0
13 0.066597000 223.109.82.212 192.168.0.12 TLSv1.2 1454 Server Hello
  1. 代码/类型:Server Hello
  2. 正在做什么:百度服务器回应你的申请。
  3. 确定算法:从你刚才提交的清单里选定了一套双方都支持的加密套件(比如 ECDHE-RSA-AES128-GCM-SHA256)。
  4. 发送 Server Random:发送服务器生成的随机数 B(后续用来计算对称密钥)。
1
2
3
4
5
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Server Hello
Handshake Protocol: Server Hello
Random: 6aab8a...d28aa2c
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)

0

1
2
3
14      0.066597000      223.109.82.212      192.168.0.12      TCP      1454      443 → 2993 [ACK] Seq=1401 Ack=1732 Win=82304 Len=1400 [TCP PDU reassembled in 17]
16 0.067020200 223.109.82.212 192.168.0.12 TCP 1454 443 → 2993 [ACK] Seq=2801 Ack=1732 Win=82304 Len=1400 [TCP PDU reassembled in 17]
17 0.067020200 223.109.82.212 192.168.0.12 TLSv1.2 1060 Certificate, Server Key Exchange, Server Hello Done
  1. 代码/类型:Certificate, Server Key Exchange, Server Hello Done(重组后的复合包)
  2. 正在做什么:服务器把握手所需的核心凭证一次性全塞给你:
  3. Certificate:把百度的 公钥数字证书 发给你,让你校验百度身份的真伪。
  4. Server Key Exchange:发送基于 ECDHE 密钥交换算法的服务器临时公钥参数(用于生成密钥,避免直接在网线上传输密钥)。
  5. Server Hello Done:宣告“服务器端的握手第一阶段信息全部发完了”。
1
2
3
4
5
6
7
8
9
10
11
Transport Layer Security
Handshake Protocol: Certificate
Certificates (4764 bytes)
Certificate Length: 2543
Certificate […]: 308209eb308208....52534120

Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Server Key Exchange
Handshake Protocol: Server Key Exchange
TLSv1.2 Record Layer: Handshake Protocol: Server Hello Done
Handshake Protocol: Server Hello Done

0

1
2
18      0.067080300      192.168.0.12      223.109.82.212      TCP      54      2993 → 443 [ACK] Seq=1732 Ack=5207 Win=263168 Len=0
19 0.070535400 192.168.0.12 223.109.82.212 TLSv1.2 180 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
  1. 代码/类型:Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
  2. 正在做什么:你的电脑验证证书通过后,完成客户端的最后握手准备:
  3. Client Key Exchange:把客户端的 ECDHE 临时公钥参数发给服务器。此时,双方已各自在本地算出了最终的对称密钥。
  4. Change Cipher Spec:正式通知服务器:“从下一字节开始,我发的所有包都必须用刚才算好的密钥加密!”
  5. Encrypted Handshake Message(Finished):发送第一段用新密钥加密的握手验证数据,供对方验证加密是否正常。
1
2
3
4
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Client Key Exchange
TLSv1.2 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec
TLSv1.2 Record Layer: Handshake Protocol: Encrypted Handshake Message

0

1
2
23      0.090828300      223.109.82.212      192.168.0.12      TCP      60      443 → 2993 [ACK] Seq=5207 Ack=1858 Win=82304 Len=0
24 0.091006000 223.109.82.212 192.168.0.12 TLSv1.2 280 New Session Ticket, Change Cipher Spec, Encrypted Handshake Message
  1. 代码/类型:New Session Ticket, Change Cipher Spec, Encrypted Handshake Message
  2. 正在做什么:服务器完成它的加密开启与确认动作:
  3. New Session Ticket:下发一个加密的 Session Ticket 给客户端保存。下次你再连百度时,直接出示这个 Ticket 就能跳过繁琐的握手(实现快速恢复连接)。
  4. Change Cipher Spec:服务器也通知你:“我也准备好了,后面我发给你的数据全都要加密了!”
  5. Encrypted Handshake Message(Finished):服务器发送加密的握手验证数据,双方至此TLS 握手彻底圆满结束。
1
2
3
4
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: New Session Ticket
TLSv1.2 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec
TLSv1.2 Record Layer: Handshake Protocol: Encrypted Handshake Message

在 TLS 握手阶段,数据包内容是“前段完全明文,后段开始加密”的。一旦包里出现了 Change Cipher Spec 那个节点,从它后面的数据开始,就必须并且已经是加密的了。

阶段一:协商算法与传递随机数(1st RTT 开始)

  1. Client Hello(客户端 → 服务端)
    • 作用:客户端发起加密连接请求。
    • 携带内容:
    • SNI(Server Name Indication):告知要访问的域名(如 [www.baidu.com](https://www.baidu.com))。
    • 客户端随机数(Client Random):在本地生成的第 1 个随机数(明文传输)。
    • 支持的加密套件列表(Cipher Suites):客户端支持的算法组合(如 ECDHE-RSA-AES128-GCM-SHA256)。
  2. Server Hello & 凭证下发(服务端 → 客户端)
    • 作用:服务端确定方案、证明自己身份并下发密钥参数。
    • 携带内容:
    • Server Hello:选定一套双方都支持的加密套件,并发送服务端生成的 第 2 个随机数(Server Random)(明文传输)。
    • Certificate:下发服务端的 数字证书(包含服务端公钥),供客户端校验身份。
    • Server Key Exchange:发送基于密钥交换算法(如 ECDHE)的服务端 临时公钥/参数。
    • Server Hello Done:告知客户端“我的第一轮汇报发完了”。

阶段二:密钥计算与开启加密(2nd RTT)

  1. Client Key Exchange & 开启客户端加密(客户端 → 服务端)
    • 作用:客户端验证证书,发送自己的密钥参数,并通知开启加密。
    • 过程与内容:
    • 验证证书:客户端检查证书合法性(CA 签发、未过期、域名匹配等)。
    • Client Key Exchange:发送 ECDHE 算法的客户端 临时公钥/参数。
    • 本地计算主密钥:此时,客户端根据 Client Random + Server Random + ECDHE 算出的预主密钥 (Pre-Master Secret)**,在本地算出了最终用于数据加解密的 “主密钥(Master Secret / Session Key)”**。
    • Change Cipher Spec:告知服务端“从下一字节开始,我发的所有数据都将用刚刚算出的主密钥加密!”
    • Encrypted Handshake Message (Finished):发送第一段用主密钥加密的校验数据,供服务端验证。
  2. 服务端确认与开启服务端加密(服务端 → 客户端)
    • 作用:服务端完成密钥计算,确认加密链路通畅,完成握手。
    • 过程与内容:
    • 本地计算主密钥:服务端根据收到的客户端 ECDHE 参数,结合之前存下的两个随机数,在本地算出了一模一样的主密钥。
    • New Session Ticket(可选):下发加密的 Session Ticket,方便下次连接时快速复用。
    • Change Cipher Spec:告知客户端“我也准备好了,后面我发的数据也全部加密!”
    • Encrypted Handshake Message (Finished):发送加密的校验数据,供客户端校验。

阶段三:应用层数据传输(Application Data)

  1. 至此,TLS 握手彻底结束。后续所有的应用层 HTTP 数据(如网页 HTML、API 请求)都会被主密钥加密后塞入 TLS 记录(Record)中,通过底层的 TCP 管道安全传输。

重新传输

1
2
21      0.080248200      223.109.82.212      192.168.0.12      TCP      1060      [TCP Spurious Retransmission] 443 → 2993 [PSH, ACK] Seq=4201 Ack=1732 Win=82304 Len=1006
22 0.080493500 192.168.0.12 223.109.82.212 TCP 66 [TCP Dup ACK 18#1] 2993 → 443 [ACK] Seq=2605 Ack=5207 Win=263168 Len=0 SLE=4201 SRE=5207s
  1. 对面自动传输 4201-5207的数据给我。(认为这个数据包丢失)
  2. 我这边回复 5207 之前的数据都收到了,并没有缺失。

现实网络中,这两种机制是在同时协同运作的,并且各自扮演着不同的角色

  1. 在实际业务(如浏览网页、看视频、下载文件)中:
    • “发现缺了直接要”(快速重传 / SACK)是处理丢包的主力军
      • 原因:因为网络一直在持续传输大量数据,后方的包会源源不断到达。一旦中间掉了一个包,客户端会立刻感知到(Seq 不连续)并连续回传 Duplicate ACK 催促。
      • 优势:触发非常极速(只要收到 3 个重复 ACK 就会触发),不需要死等几百毫秒的定时器,对网速和延迟影响极小。
    • “超时自动重发”(RTO 重传)是最后的保底防线
      • 原因:如果发生严重拥堵(比如后面的包全丢了,或者这是发送方发的最后一个包),客户端根本没有机会收到后续数据包来触发“催促”信号。
      • 作用:此时只能靠发送方自己的 RTO 定时器硬等。定时器一响,不管三七二十一立刻重发。
      • 代价:RTO 超时通常会导致明显卡顿(因为通常要等数百毫秒以上),TCP 还会顺便把拥塞窗口(cwnd)剧烈缩小。
  2. 两种机制的对比
机制 触发主体 触发条件 适用场景 效率
快速重传 (Fast Retransmit) 接收方催促 接收方发现缺包,连续发 3 个 Duplicate ACK / SACK 持续传输中偶发丢包 极高(毫秒级响应,不打断传输节奏)
超时重传 (RTO Retransmit) 发送方自动 发送方本地 RTO 定时器到期,仍未收到 ACK 严重拥塞、尾包丢失或 ACK 全丢 较低(需死等超时,会降低传输速度)

回看你刚才的抓包案例(包 21)

抓到的包 21 属于第二种(超时重传),但它属于一种“误判导致的虚假重传”:

  1. 服务端的 RTO 定时器设得稍微太敏感了,或者网络延迟忽然抖动了一下(ACK 回传慢了)。
  2. 服务端没等到 ACK,定时器到期,于是自动重发了包 21。
  3. 结果你的电脑收到后一比对:“这包我早收到了呀!”于是回了个包 22(Dup ACK)告诉对方:“收到了,进度已更新,别发了!”

网络抓包-TCP
https://fu01.github.io/posts/d7333f1c/
作者
Fu01
发布于
2026年9月17日
许可协议