15天:TCP协议基础

第15天:TCP协议基础

今日目标

  • 理解TCP协议的核心特性
  • 掌握TCP报文格式
  • 深入理解TCP三次握手过程
  • 深入理解TCP四次挥手过程
  • 掌握TCP状态机转换
  • 实现TCP连接分析工具

1. TCP协议概述

1.1 什么是TCP?

TCP(Transmission Control Protocol,传输控制协议) 是互联网协议套件中最重要的协议之一。

生活类比

TCP就像打电话:
1. 拨号等待对方接听(建立连接)
2. 双方确认能听清楚(三次握手)
3. 开始对话(数据传输)
4. 说"再见"挂断电话(四次挥手)

特点:
✅ 可靠:说的每句话对方都能听到
✅ 有序:对话内容按顺序传递
✅ 面向连接:必须先建立连接才能通话

1.2 TCP的核心特性

TCP = 可靠的、面向连接的、字节流协议

1. 面向连接(Connection-Oriented)
   ├── 通信前必须建立连接
   ├── 通信后必须释放连接
   └── 类似打电话

2. 可靠传输(Reliable)
   ├── 数据不丢失
   ├── 数据不重复
   ├── 数据按序到达
   └── 通过确认和重传机制实现

3. 全双工通信(Full-Duplex)
   ├── 双方可同时发送和接收
   └── 类似电话可以双向对话

4. 字节流服务(Byte Stream)
   ├── 面向字节流,不是消息流
   ├── 应用层交给TCP的数据可能被拆分或合并
   └── 没有消息边界

5. 流量控制(Flow Control)
   ├── 防止发送方发送过快
   └── 通过滑动窗口实现

6. 拥塞控制(Congestion Control)
   ├── 防止网络过载
   └── 慢启动、拥塞避免等算法

1.3 TCP vs UDP

特性TCPUDP
连接面向连接无连接
可靠性可靠(确认+重传)不可靠(尽力而为)
顺序保证顺序不保证顺序
速度较慢(开销大)快速(开销小)
头部开销20-60字节8字节
流量控制
拥塞控制
数据边界字节流(无边界)数据报(有边界)
应用场景HTTP、FTP、邮件DNS、视频、游戏

使用场景对比

选择TCP:
✅ 需要可靠传输(文件下载、网页浏览)
✅ 数据完整性重要(银行转账、邮件)
✅ 顺序很重要(聊天消息)

选择UDP:
✅ 实时性要求高(视频通话、游戏)
✅ 可以容忍少量丢包(直播、语音)
✅ 数据量小且频繁(DNS查询)
✅ 广播/组播通信

2. TCP报文格式

2.1 TCP段结构

TCP传输的数据单元称为段(Segment)

TCP段 = TCP头部 + 数据

┌─────────────────────────────────────────────────────┐
│                    TCP 头部                          │
│                  (20-60 字节)                        │
├─────────────────────────────────────────────────────┤
│                    应用数据                          │
│                   (可变长度)                         │
└─────────────────────────────────────────────────────┘

2.2 TCP头部格式(20字节最小)

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          源端口 (16位)         |        目标端口 (16位)         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        序列号 (32位)                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      确认号 (32位)                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  头部  |       |C|E|U|A|P|R|S|F|                               |
|  长度  | 保留  |W|C|R|C|S|S|Y|I|          窗口大小 (16位)       |
|  (4位) | (3位) |R|E|G|K|H|T|N|N|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          校验和 (16位)         |        紧急指针 (16位)         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    选项 (可变长度,最多40字节)                  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          数据                                  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

2.3 字段详解

1. 源端口和目标端口(各16位)

用途:标识发送方和接收方的应用进程

示例:
源端口: 54321 (客户端随机端口)
目标端口: 80 (HTTP服务器端口)

2. 序列号(Sequence Number,32位)

作用:
- 标识发送的数据字节流中的位置
- 确保数据按序到达
- 范围:0 ~ 4,294,967,295

示例:
第1个TCP段:SEQ = 1000,数据长度100字节
第2个TCP段:SEQ = 1100 (1000 + 100)
第3个TCP段:SEQ = 1200

3. 确认号(Acknowledgment Number,32位)

作用:
- 期望收到的下一个字节的序列号
- ACK=1000 表示"我已收到999及之前的所有数据,期望收到1000"

特点:
- 累积确认(确认号之前的所有数据都已收到)

4. 头部长度(4位)

单位:32位字(4字节)
范围:5-15(表示20-60字节)

最小值:5 × 4 = 20字节(无选项)
最大值:15 × 4 = 60字节(40字节选项)

5. 保留位(3位)

保留未来使用,必须置0

6. 控制标志位(9位)

最重要的6个标志:

1. URG (Urgent,紧急)
   - URG=1 表示紧急指针有效
   - 很少使用

2. ACK (Acknowledgment,确认)
   - ACK=1 表示确认号有效
   - 除了第一个SYN包,其他都是1

3. PSH (Push,推送)
   - PSH=1 要求立即推送数据给应用层
   - 不要缓冲

4. RST (Reset,重置)
   - RST=1 重置连接
   - 用于异常关闭或拒绝连接

5. SYN (Synchronize,同步)
   - SYN=1 请求建立连接
   - 用于三次握手

6. FIN (Finish,结束)
   - FIN=1 请求关闭连接
   - 用于四次挥手

其他3个(较新):
- CWR: Congestion Window Reduced (拥塞窗口减少)
- ECE: ECN Echo (显式拥塞通知回显)
- NS: Nonce Sum (随机数和)

7. 窗口大小(16位)

作用:流量控制
含义:告诉对方自己的接收缓冲区还能接收多少字节

范围:0 ~ 65535 字节
窗口=0 表示"暂停发送,我的缓冲区满了"

示例:
Window = 8192 → "我最多还能接收8KB数据"

8. 校验和(16位)

作用:检测TCP段在传输过程中是否出错

计算范围:
- TCP伪头部(来自IP层)
- TCP头部
- TCP数据

如果校验失败 → 丢弃该段

9. 紧急指针(16位)

仅当URG=1时有效
指向紧急数据的最后一个字节

很少使用

10. 选项(可变长度)

常用选项:

1. MSS (Maximum Segment Size,最大段大小)
   - 选项类型: 2
   - 长度: 4字节
   - 表示愿意接收的最大TCP段大小
   - 通常在SYN包中协商

2. Window Scale (窗口扩大因子)
   - 选项类型: 3
   - 长度: 3字节
   - 扩大窗口大小(突破65535限制)
   - 实际窗口 = Window × 2^Scale

3. Timestamps (时间戳)
   - 选项类型: 8
   - 长度: 10字节
   - 用于计算RTT和防止序列号回绕

4. SACK (Selective Acknowledgment,选择性确认)
   - 选项类型: 5
   - 允许确认不连续的数据块

3. TCP三次握手

3.1 为什么需要三次握手?

目的

  1. 确认双方的发送和接收能力都正常
  2. 协商初始序列号(ISN)
  3. 协商连接参数(MSS、窗口大小等)

为什么不是两次或四次?

两次握手的问题:
- 客户端发送SYN
- 服务器回复SYN+ACK
❌ 服务器不知道客户端是否收到SYN+ACK
❌ 可能导致半开连接(服务器以为连接建立,客户端不知道)
❌ 旧的重复SYN可能导致资源浪费

三次握手刚好:
✅ 确认双方都能发送和接收
✅ 防止旧连接的初始化
✅ 资源开销合理

四次握手:
⚠️ 没必要,增加延迟

3.2 三次握手详细过程

客户端                                          服务器
CLOSED                                          LISTEN
  |                                                |
  |  ① SYN=1, SEQ=x                               |
  |  "你好,我想建立连接,我的初始序列号是x"        |
  |─────────────────────────────────────────────>|
  |                                                |
SYN_SENT                                          |
  |                                                |
  |  ② SYN=1, ACK=1, SEQ=y, ACK_NUM=x+1           |
  |  "好的,我同意。我的初始序列号是y,确认收到x"   |
  |<─────────────────────────────────────────────|
  |                                          SYN_RCVD
  |                                                |
  |  ③ ACK=1, SEQ=x+1, ACK_NUM=y+1                |
  |  "收到,我们开始通信吧!"                       |
  |─────────────────────────────────────────────>|
  |                                                |
ESTABLISHED                              ESTABLISHED
  |                                                |
  |            数据传输...                         |
  |<─────────────────────────────────────────────>|

第一次握手(客户端 → 服务器)

TCP标志:SYN = 1
序列号:  SEQ = x (客户端随机选择的ISN)
确认号:  无效(ACK=0)

客户端状态:CLOSED → SYN_SENT
服务器状态:LISTEN(保持不变)

作用:
- 客户端告诉服务器:"我想建立连接"
- 告诉服务器客户端的初始序列号

第二次握手(服务器 → 客户端)

TCP标志:SYN = 1, ACK = 1
序列号:  SEQ = y (服务器随机选择的ISN)
确认号:  ACK_NUM = x + 1

客户端状态:SYN_SENT(保持不变)
服务器状态:LISTEN → SYN_RCVD

作用:
- 服务器告诉客户端:"我同意建立连接"
- 告诉客户端服务器的初始序列号
- 确认收到了客户端的SYN(ACK=x+1)

第三次握手(客户端 → 服务器)

TCP标志:ACK = 1
序列号:  SEQ = x + 1
确认号:  ACK_NUM = y + 1

客户端状态:SYN_SENT → ESTABLISHED ✅
服务器状态:SYN_RCVD → ESTABLISHED ✅

作用:
- 客户端确认收到服务器的SYN+ACK
- 双方进入ESTABLISHED状态,可以开始传输数据

3.3 三次握手抓包示例

Wireshark抓包分析

第1个包:客户端 → 服务器
TCP 54321 → 80 [SYN] Seq=0 Win=65535 Len=0 MSS=1460

第2个包:服务器 → 客户端
TCP 80 → 54321 [SYN, ACK] Seq=0 Ack=1 Win=29200 Len=0 MSS=1460

第3个包:客户端 → 服务器
TCP 54321 → 80 [ACK] Seq=1 Ack=1 Win=65535 Len=0

✅ 连接建立成功

3.4 三次握手的常见问题

Q1:第三次握手失败会怎样?

情况:
- 客户端发送第三次ACK
- ACK在网络中丢失,服务器没收到

服务器行为:
1. 服务器仍然处于SYN_RCVD状态
2. 等待超时后重传SYN+ACK
3. 重传几次后(默认5次)放弃,关闭连接

客户端行为:
1. 客户端已进入ESTABLISHED状态
2. 可以发送数据
3. 服务器收到数据包(含ACK)后也进入ESTABLISHED

Q2:SYN洪水攻击(SYN Flood)是什么?

攻击原理:
1. 攻击者发送大量SYN请求
2. 使用伪造的源IP地址
3. 服务器回复SYN+ACK到不存在的地址
4. 服务器维护大量半开连接(SYN_RCVD状态)
5. 耗尽服务器资源

防护措施:
- SYN Cookie技术
- 限制SYN请求速率
- 减少超时时间
- 增加半连接队列大小

4. TCP四次挥手

4.1 为什么需要四次挥手?

核心原因:TCP是全双工通信,双方都需要独立关闭自己的发送通道。

建立连接:握手(单向,一起建立)
关闭连接:挥手(双向,独立关闭)

类比:
建立电话:双方同时准备好就行
挂断电话:每个人都要说"再见"并确认

4.2 四次挥手详细过程

客户端                                          服务器
ESTABLISHED                              ESTABLISHED
  |                                                |
  |  ① FIN=1, SEQ=u                               |
  |  "我没有数据要发送了,准备关闭"                 |
  |─────────────────────────────────────────────>|
  |                                                |
FIN_WAIT_1                                        |
  |                                                |
  |  ② ACK=1, SEQ=v, ACK_NUM=u+1                  |
  |  "好的,我知道了。但我可能还有数据要发送"        |
  |<─────────────────────────────────────────────|
  |                                          CLOSE_WAIT
FIN_WAIT_2                                        |
  |                                                |
  |            服务器继续发送数据...                |
  |<─────────────────────────────────────────────|
  |                                                |
  |  ③ FIN=1, ACK=1, SEQ=w, ACK_NUM=u+1           |
  |  "好了,我的数据也发送完了,可以关闭了"          |
  |<─────────────────────────────────────────────|
  |                                          LAST_ACK
TIME_WAIT                                         |
  |                                                |
  |  ④ ACK=1, SEQ=u+1, ACK_NUM=w+1                |
  |  "收到,再见!"                                |
  |─────────────────────────────────────────────>|
  |                                                |
  |                                            CLOSED
  |  (等待2MSL时间)                               |
  |                                                |
CLOSED                                            |

第一次挥手(客户端 → 服务器)

TCP标志:FIN = 1, ACK = 1
序列号:  SEQ = u
确认号:  ACK_NUM = v

客户端状态:ESTABLISHED → FIN_WAIT_1
服务器状态:ESTABLISHED(保持不变)

含义:
- 客户端告诉服务器:"我没有数据要发送了"
- 客户端进入主动关闭状态
- 但客户端仍可以接收数据

第二次挥手(服务器 → 客户端)

TCP标志:ACK = 1
序列号:  SEQ = v
确认号:  ACK_NUM = u + 1

客户端状态:FIN_WAIT_1 → FIN_WAIT_2
服务器状态:ESTABLISHED → CLOSE_WAIT

含义:
- 服务器确认收到客户端的FIN
- 服务器可能还有数据要发送
- 服务器到客户端的方向还未关闭

第三次挥手(服务器 → 客户端)

TCP标志:FIN = 1, ACK = 1
序列号:  SEQ = w
确认号:  ACK_NUM = u + 1

客户端状态:FIN_WAIT_2(保持不变)
服务器状态:CLOSE_WAIT → LAST_ACK

含义:
- 服务器数据发送完毕
- 服务器请求关闭连接
- 等待客户端最后的确认

第四次挥手(客户端 → 服务器)

TCP标志:ACK = 1
序列号:  SEQ = u + 1
确认号:  ACK_NUM = w + 1

客户端状态:FIN_WAIT_2 → TIME_WAIT → CLOSED
服务器状态:LAST_ACK → CLOSED ✅

含义:
- 客户端确认收到服务器的FIN
- 服务器收到后立即关闭
- 客户端等待2MSL时间后关闭

4.3 TIME_WAIT状态

为什么需要TIME_WAIT?

客户端在发送最后一个ACK后不立即关闭,而是等待**2MSL(Maximum Segment Lifetime)**时间。

原因1:确保最后的ACK被服务器收到

场景:
1. 客户端发送最后的ACK
2. ACK在网络中丢失
3. 服务器超时重传FIN
4. 如果客户端已关闭,无法响应
5. 服务器会认为连接异常

解决:
客户端等待2MSL
如果收到重传的FIN,重新发送ACK

原因2:确保旧连接的数据包消失

场景:
1. 旧连接关闭
2. 立即用相同的四元组建立新连接
3. 旧连接的延迟数据包到达
4. 新连接收到旧数据,导致混乱

解决:
等待2MSL,确保所有数据包都消失
(1 MSL去程 + 1 MSL回程)

MSL时间

RFC定义:2分钟
Linux默认:60秒(可调整)
Windows:4分钟

2MSL:
- Linux: 120秒
- Windows: 240秒

TIME_WAIT过多的问题

现象:
netstat -an | grep TIME_WAIT | wc -l
显示大量TIME_WAIT连接

影响:
- 占用端口(客户端端口有限)
- 占用系统资源

解决方案:
1. 启用SO_REUSEADDR选项
2. 调整内核参数:
   net.ipv4.tcp_tw_reuse = 1
   net.ipv4.tcp_tw_recycle = 1
3. 减少MSL时间(需谨慎)
4. 使用连接池复用连接

4.4 四次挥手的特殊情况

情况1:三次挥手(同时关闭)

场景:双方同时发送FIN

客户端                      服务器
   |         FIN             |
   |───────────────────────>|
   |         FIN             |
   |<───────────────────────|
   |         ACK             |
   |───────────────────────>|
   |         ACK             |
   |<───────────────────────|

结果:只需要3次握手(两个FIN + 两个ACK)

情况2:异常关闭(RST)

发送RST的情况:
1. 连接不存在时收到非SYN包
2. 连接队列溢出
3. 端口未监听
4. 应用程序调用close()时还有未读数据

RST特点:
- 立即关闭连接
- 不经过TIME_WAIT
- 接收方不发送ACK

5. TCP状态机

5.1 完整的TCP状态转换图

                              CLOSED
                                |
                                | (被动打开/listen)
                                ↓
                              LISTEN ←───────────┐
                                |                 │
            (主动打开/connect)  |                 │
                  ↓             |                 │
               SYN_SENT         | 收到SYN          │
                  |             | 发送SYN+ACK      │
         收到SYN+ACK|           ↓                 │
         发送ACK    |        SYN_RCVD              │
                  ↓             |                 │
                  └─────→ ESTABLISHED ←───────────┘
                              |   |
                  (主动关闭)  |   | (被动关闭)
                  发送FIN     |   | 收到FIN
                              |   | 发送ACK
                              ↓   ↓
                        FIN_WAIT_1  CLOSE_WAIT
                              |        |
                  收到ACK     |        | (应用层关闭)
                              |        | 发送FIN
                              ↓        ↓
                        FIN_WAIT_2  LAST_ACK
                              |        |
                  收到FIN     |        | 收到ACK
                  发送ACK     |        |
                              ↓        ↓
                         TIME_WAIT  CLOSED
                              |
                   (等待2MSL) |
                              ↓
                           CLOSED

5.2 11种TCP状态详解

状态说明所处阶段
CLOSED关闭状态,无连接初始/结束
LISTEN监听状态,等待连接服务器
SYN_SENT发送SYN后,等待SYN+ACK客户端三次握手
SYN_RCVD收到SYN,发送SYN+ACK,等待ACK服务器三次握手
ESTABLISHED连接建立,可以传输数据数据传输
FIN_WAIT_1主动关闭,发送FIN,等待ACK或FIN主动关闭方
FIN_WAIT_2收到对方ACK,等待对方FIN主动关闭方
TIME_WAIT收到FIN,发送ACK,等待2MSL主动关闭方
CLOSE_WAIT收到对方FIN,发送ACK,等待关闭被动关闭方
LAST_ACK发送FIN,等待最后的ACK被动关闭方
CLOSING双方同时关闭,等待ACK同时关闭

5.3 查看TCP连接状态

Linux/Mac

# 查看所有TCP连接
netstat -ant

# 统计各状态连接数
netstat -ant | awk '{print $6}' | sort | uniq -c

# 查看ESTABLISHED连接
netstat -ant | grep ESTABLISHED

# 查看TIME_WAIT连接
netstat -ant | grep TIME_WAIT

# 使用ss命令(更快)
ss -ant
ss -ant state established
ss -ant state time-wait

Windows

# 查看所有TCP连接
netstat -ano

# 查看指定端口
netstat -ano | findstr :80

# 查看连接统计
netstat -s -p tcp

6. 实战项目:TCP连接分析工具

6.1 项目功能

实现一个工具来:

  1. 模拟TCP三次握手
  2. 捕获和分析TCP连接
  3. 显示连接状态统计
  4. 检测异常连接

6.2 工具演示

# 查看TCP连接统计
python day15_tcp_analyzer.py --stats

# 监控指定端口的TCP连接
python day15_tcp_analyzer.py --monitor 80

# 测试TCP连接
python day15_tcp_analyzer.py --test www.baidu.com 80

# 显示连接状态分布
python day15_tcp_analyzer.py --state-distribution

7. 今日练习

练习1:观察三次握手

使用Wireshark抓包:

  1. 访问一个网站(如www.baidu.com)
  2. 筛选TCP流:tcp.port == 80
  3. 找到三次握手的三个包
  4. 分析每个包的标志位、序列号、确认号

练习2:查看本机TCP连接

# Linux/Mac
netstat -ant | grep ESTABLISHED
ss -ant state established

# Windows
netstat -ano | findstr ESTABLISHED

思考:
1. 有多少个ESTABLISHED连接?
2. 它们连接到哪些服务器?
3. 有没有TIME_WAIT状态的连接?

练习3:计算三次握手时延

抓包分析:
- 记录第1个SYN的时间戳:t1
- 记录第2个SYN+ACK的时间戳:t2
- 记录第3个ACK的时间戳:t3

计算:
- 客户端到服务器RTT: (t2 - t1) × 2
- 完整握手时延: t3 - t1

练习4:理解TIME_WAIT

编写程序:
1. 创建TCP客户端
2. 连接服务器
3. 主动关闭连接
4. 使用netstat查看TIME_WAIT状态
5. 观察2MSL时间后状态变化

8. 常见问题

Q1:为什么建立连接是三次握手,关闭连接是四次挥手?

A:

  • 建立连接:服务器可以把SYN和ACK合并在一个包中发送(SYN+ACK)
  • 关闭连接:服务器收到FIN后,可能还有数据要发送,所以ACK和FIN要分开发送

Q2:如果三次握手的第三次ACK丢失会怎样?

A:

  • 服务器会重传SYN+ACK(最多5次)
  • 客户端已经认为连接建立,可以发送数据
  • 服务器收到数据包(含ACK)后也认为连接建立

Q3:为什么TIME_WAIT要等2MSL?

A:

  1. 确保最后的ACK能够到达对方(1个MSL)
  2. 如果对方没收到,重传FIN需要1个MSL返回
  3. 确保旧连接的所有数据包都已消失

Q4:大量TIME_WAIT连接有什么危害?

A:

  • 占用本地端口(客户端)
  • 消耗系统资源(内存、CPU)
  • 可能导致无法建立新连接

解决:

  • 使用连接池
  • 启用SO_REUSEADDR
  • 调整系统参数

Q5:客户端和服务器都可以主动关闭连接吗?

A:

  • 可以,任何一方都可以主动发送FIN
  • 主动关闭方会进入TIME_WAIT状态
  • 这就是为什么服务器端通常设计为由客户端主动关闭

9. 总结

今天我们学习了:

核心知识点

  1. TCP特性

    • 面向连接
    • 可靠传输
    • 全双工通信
    • 字节流服务
  2. TCP报文格式

    • 20字节固定头部
    • 重要字段:序列号、确认号、标志位、窗口大小
  3. 三次握手

    • SYN → SYN+ACK → ACK
    • 目的:确认双方能力、协商参数、防止旧连接
  4. 四次挥手

    • FIN → ACK → FIN → ACK
    • 原因:全双工,双向独立关闭
    • TIME_WAIT:等待2MSL
  5. TCP状态机

    • 11种状态
    • 状态转换条件
    • 异常情况处理

重点回顾

TCP三次握手:
1️⃣ 客户端 → 服务器:SYN
2️⃣ 服务器 → 客户端:SYN+ACK
3️⃣ 客户端 → 服务器:ACK
✅ 连接建立

TCP四次挥手:
1️⃣ 客户端 → 服务器:FIN
2️⃣ 服务器 → 客户端:ACK
3️⃣ 服务器 → 客户端:FIN
4️⃣ 客户端 → 服务器:ACK
⏳ TIME_WAIT (2MSL)
✅ 连接关闭

明天预告

第16天:TCP可靠传输机制

内容预览:

  • 序列号和确认号详解
  • 滑动窗口机制
  • 超时重传
  • 快速重传和快速恢复
  • 流量控制
  • 拥塞控制

继续加油! 🚀

今天我们深入学习了TCP协议的基础知识,理解了三次握手和四次挥手的完整过程。这些是TCP协议的核心,也是网络面试的高频考点。明天我们将学习TCP如何实现可靠传输!