理论课40分钟

23课:TCP协议详解

可靠传输的保障

教学目标

1掌握TCP报文段的结构
2理解三次握手和四次挥手
3了解TCP的流量控制和拥塞控制

📖 课前导入

网络层(IP协议)负责把数据包从源主机送到目的主机,但它是不可靠的——不保证数据包一定到达,也不保证到达的顺序。

谁来保证数据传输的可靠性?答案是传输层的TCP协议!它提供面向连接的、可靠的、字节流服务。

今天我们来深入学习TCP——互联网上最重要的传输协议!

📚 一、TCP协议概述

TCP的核心特点

TCP(Transmission Control Protocol,传输控制协议)提供面向连接的、可靠的、基于字节流的传输服务。它是HTTP、FTP、SMTP、SSH等绝大多数应用层协议的底层传输。

🤝

面向连接

通信前先建立连接(三次握手)

可靠传输

确认、重传、排序保证数据完整

📊

流量控制

接收方控制发送速率

🚦

拥塞控制

根据网络状况调整发送速率

📚 二、TCP报文段结构 ⭐核心内容

TCP首部格式(20字节固定 + 可变选项)

源端口号(16位)
目的端口号(16位)
序号 Sequence Number(32位)
确认号 Acknowledgment Number(32位)
数据偏移(4位)
保留
标志位(URG ACK PSH RST SYN FIN)
窗口大小(16位)
校验和(16位)
紧急指针(16位)
选项(可变长度)+ 填充

源端口 / 目的端口 —— 各16位

标识发送方和接收方的应用进程。范围0~65535。

序号(Seq)—— 32位

本报文段数据部分第一个字节的编号。TCP以字节为单位编号,保证数据按顺序重组。

确认号(Ack)—— 32位

期望收到对方下一个字节的编号。例如Ack=1001表示"1000及之前的数据我都收到了,请发1001"。

标志位 ⭐重要

SYN:请求建立连接
ACK:确认号有效
FIN:请求释放连接
RST:重置连接
PSH:尽快交付应用层
URG:紧急数据

窗口大小 —— 16位

接收方告诉发送方"我还能接收多少数据",用于流量控制。单位是字节。

📚 三、三次握手 ⭐⭐⭐必考

🎯 生活类比:打电话

1

小明拨号"喂,你好,我是小明,能听到吗?" (第1次握手:我能发消息)

2

小红回应"听到了!我是小红,你能听到我吗?" (第2次握手:我能收也能发)

3

小明确认"听到了!那我们开始聊吧!" (第3次握手:双方确认完毕,开始通话)

💡 三次对话的目的:双方都确认了"我能听到你"且"你能听到我"。TCP三次握手道理完全一样!

🎬 TCP三次握手交互式动画

步骤 1 / 5

客户端

CLOSED

服务器

LISTEN

初始状态:客户端关闭,服务器监听

💡 服务器已在端口上等待客户端连接请求

为什么需要三次握手?

TCP是面向连接的协议,通信前必须先建立连接。三次握手(Three-Way Handshake)有两个目的:

  1. 确认双方的发送和接收能力——确保客户端和服务器都能正常收发数据
  2. 同步初始序号(ISN)——让双方知道从哪个编号开始计数

═══ TCP 三次握手时序图 ═══

客户端 (Client) 服务器 (Server) ┌──────────┐ ┌──────────┐ │ CLOSED │ │ LISTEN │ └────┬─────┘ └────┬─────┘ │ │ │ ① SYN=1, Seq=1000 │ │ ──────────────────────────────────────> │ │ "你好,我要建立连接" │ │ │ ┌────┴─────┐ ┌────┴─────┐ │ SYN_SENT │ │ SYN_RCVD │ └────┬─────┘ └────┬─────┘ │ │ │ ② SYN=1, ACK=1, Seq=2000, Ack=1001 │ │ <────────────────────────────────────── │ │ "好的,我也要连接" │ │ │ ┌────┴──────┐ ┌────┴─────┐ │ESTABLISHED│ │ SYN_RCVD │ └────┬──────┘ └────┬─────┘ │ │ │ ③ ACK=1, Seq=1001, Ack=2001 │ │ ──────────────────────────────────────> │ │ "收到,连接建立!" │ │ │ ┌────┴──────┐ ┌────┴──────┐ │ESTABLISHED│ │ESTABLISHED│ └───────────┘ └───────────┘ │ │ │ ◄───── 双向数据传输开始 ─────► │

🔍 逐步详解

1

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

发送内容:SYN报文

SYN = 1(请求连接标志)

Seq = 1000(初始序号,随机生成)

ACK = 0(此时无确认)

🗣️ 通俗解读

"服务器你好!我是客户端,我想和你建立连接。我的起始编号是1000,以后我发的数据从这个编号开始。"

📌 客户端状态:CLOSED → SYN_SENT(已发送SYN,等待回复)

📌 服务器状态:LISTEN(一直在监听端口等待连接)

2

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

发送内容:SYN+ACK报文

SYN = 1(服务器也请求连接)

ACK = 1(确认收到客户端的SYN)

Seq = 2000(服务器的初始序号)

Ack = 1001(= 客户端Seq + 1)

🗣️ 通俗解读

"客户端你好!你的请求我收到了(ACK)。我也想和你建立连接(SYN)。我的起始编号是2000。你下次发数据请从编号1001开始(Ack=1001)。"

📌 客户端状态:SYN_SENT(还在等)

📌 服务器状态:LISTEN → SYN_RCVD(已收到SYN,等待最终确认)

关键点:第二次握手做了两件事——①确认客户端的请求(ACK) + ②发送自己的连接请求(SYN),所以称为 SYN+ACK 报文。

3

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

发送内容:ACK报文

ACK = 1(确认收到服务器的SYN)

Seq = 1001(= 之前的Seq + 1)

Ack = 2001(= 服务器Seq + 1)

🗣️ 通俗解读

"服务器,你的回复我也收到了!连接正式建立,我们开始传数据吧!"

📌 客户端状态:SYN_SENT → ESTABLISHED(连接已建立!)

📌 服务器状态:SYN_RCVD → ESTABLISHED(连接已建立!)

此时双方状态都是 ESTABLISHED,可以开始双向数据传输了!第三次握手可以携带数据。

📊 三次握手确认了什么?

握手次数客户端发送能力客户端接收能力服务器发送能力服务器接收能力
第1次握手后✅ 确认
第2次握手后✅ 确认✅ 确认✅ 确认✅ 确认
第3次握手后✅ 双方确认✅ 双方确认✅ 双方确认✅ 双方确认

💡 第2次握手后客户端已知道双方能力正常,但服务器还不知道自己的SYN+ACK是否被客户端收到,所以需要第3次握手来确认。

小贴士

为什么是三次?不是两次或四次?

❌ 两次握手的问题

假设客户端之前发了一个旧的SYN请求(因网络延迟还在路上),后来又发了新的SYN。如果只有两次握手:

  1. 旧SYN到达服务器 → 服务器以为是新请求,回复SYN+ACK → 错误地建立了连接
  2. 服务器白白分配资源等待数据,但客户端根本不会发数据 → 资源浪费!

✅ 三次握手的解决

客户端收到旧SYN对应的SYN+ACK后,发现序号不对,会发RST拒绝。三次握手让双方都有机会验证,避免了历史连接的混乱。

❌ 四次握手没必要

三次已经够了!第二次握手把SYN和ACK合并在一个报文中发送,没必要拆成两个。多一次就是浪费时间和带宽。

🌐 三次握手状态变迁图

发送SYN收到SYN,回复SYN+ACK收到SYN+ACK,发送ACK收到ACK
CLOSED(关闭)
LISTEN(监听)
SYN_SENT(已发SYN)
SYN_RCVD(已收SYN)
ESTABLISHED(客户端就绪)
ESTABLISHED(服务器就绪)

🔬 Wireshark 抓包验证

用 Wireshark 抓包访问百度网站,可以清晰看到三次握手的真实数据:

Wireshark 抓包:TCP三次握手
// 模拟终端 - 点击"执行下一条"或按回车运行命令
// 共 2 条命令,已执行 0
C:\>

📝 考试速记口诀

口诀一:SYN-SYN/ACK-ACK

第1次:客户端发 SYN

第2次:服务器回 SYN+ACK

第3次:客户端发 ACK

口诀二:请求-同意-确认

第1次:"我要连接" (请求)

第2次:"同意,我也要连接" (同意+请求)

第3次:"好的,开始吧" (确认)

⚠️ 易错点

  • Ack(确认号)= 对方的Seq + 1,不要搞反
  • 第三次握手时 SYN=0(不是1!),只有ACK=1
  • 第三次握手可以携带数据,前两次不行

📚 四、四次挥手 ⭐⭐必考

连接释放——四次挥手

TCP连接的释放需要四次挥手(Four-Way Handshake)。因为TCP是全双工的,每个方向的关闭需要独立进行。

第1次挥手:客户端 → FIN

FIN=1, Seq=u | "我的数据发完了,请求关闭连接"

第2次挥手:服务器 → ACK

ACK=1, Ack=u+1 | "知道了,但我可能还有数据要发"

此时客户端→服务器方向关闭,但服务器→客户端方向仍可发数据(半关闭状态)

第3次挥手:服务器 → FIN

FIN=1, ACK=1, Seq=w | "我的数据也发完了,请求关闭"

第4次挥手:客户端 → ACK

ACK=1, Ack=w+1 | "好的,连接释放"

客户端进入TIME_WAIT状态,等待2MSL后才真正关闭

知识点

为什么需要TIME_WAIT?

客户端发送最后一个ACK后,不能立即关闭,而是等待2MSL(Maximum Segment Lifetime,最大报文生存时间)。原因:

  1. 确保最后的ACK能到达服务器(如果丢了,服务器会重发FIN,客户端可以再次确认)
  2. 等待本连接的所有残留报文在网络中消失,避免影响新连接

📚 五、流量控制与拥塞控制

流量控制(Flow Control)

目的:防止发送方发送过快,超出接收方的处理能力。

机制:接收方在ACK中通过窗口大小字段告诉发送方自己的接收缓冲区还剩多少空间。发送方据此调整发送量。

类比:水管往桶里灌水,桶快满时要减小水流。

拥塞控制(Congestion Control)

目的:防止过多数据涌入网络,导致网络拥塞崩溃。

机制:发送方维护一个拥塞窗口,根据网络反馈动态调整。

类比:高速公路堵车时要限流。

拥塞控制的四个阶段

1. 慢启动(Slow Start)

拥塞窗口从1MSS开始,每收到一个ACK翻倍增长(指数增长),直到达到慢启动阈值。

2. 拥塞避免(Congestion Avoidance)

超过阈值后,每个RTT窗口只增加1MSS(线性增长),小心探测网络容量。

3. 快重传(Fast Retransmit)

收到3个重复ACK时,立即重传丢失的报文段,不等超时。

4. 快恢复(Fast Recovery)

快重传后,阈值减半,窗口从新阈值开始线性增长(而不是从1开始)。

TCP三次握手与四次挥手动画详解

通过动画演示三次握手建立连接和四次挥手释放连接的完整过程,配合Wireshark抓包验证

12:00
TCP三次握手与四次挥手动画详解推荐视频12:00

通过动画演示三次握手建立连接和四次挥手释放连接的完整过程,配合Wireshark抓包验证

✅ 课堂小测

随堂测验

1/5

TCP三次握手中,第二次握手的报文标志位是?

🧠 独立思考题

以下问题没有标准答案,需要你结合所学知识独立思考、小组讨论,锻炼分析问题的能力。

1

如果第三次握手的 ACK 丢了,会发生什么?

提示:思考以下几点——

  • 此时客户端认为连接已建立,服务器呢?
  • 如果客户端立刻发送数据,服务器会怎么处理?
  • 服务器会一直等下去吗?还是有超时机制?

💡 思考方向

服务器处于 SYN_RCVD 状态,会重传 SYN+ACK。如果客户端此时发送了带 ACK 的数据包,服务器收到后也能确认连接。如果一直收不到,服务器最终超时关闭。

2

什么是 SYN 洪水攻击(SYN Flood)?它利用了三次握手的什么弱点?

提示:思考以下几点——

  • 攻击者发送大量 SYN 请求,但故意不完成第三次握手
  • 服务器会为每个"半连接"分配什么资源?
  • 当半连接队列被占满后,正常用户还能连接吗?
  • 你能想到什么防御方法?

💡 思考方向

每收到一个SYN,服务器就要在半连接队列中分配内存等资源。攻击者用伪造IP大量发SYN却不回ACK,导致队列溢出。防御方法包括:SYN Cookie(不分配资源,用算法验证)、限制半连接数、缩短SYN_RCVD超时等。

3

为什么建立连接需要三次握手,而释放连接需要四次挥手?能不能统一?

提示:对比思考——

  • 建立连接时,服务器的 SYN 和 ACK 为什么能合并成一个报文?
  • 释放连接时,服务器的 FIN 和 ACK 为什么不能合并?
  • 关键区别在于:收到对方的关闭请求后,自己是否还有数据要发?

💡 思考方向

建立连接时双方都还没发数据,服务器可以立刻同意并发起自己的请求(SYN+ACK合并)。但释放连接时,服务器可能还有未发完的数据,必须先ACK确认收到关闭请求,等数据发完后再发FIN,所以ACK和FIN只能分开发。

4

你在浏览器输入 www.baidu.com 后按回车,这个过程中发生了几次三次握手?

提示:拆解整个过程——

  • DNS 查询用的是 TCP 还是 UDP?需要三次握手吗?
  • 访问 HTTP/HTTPS 网页需要和 Web 服务器建立 TCP 连接吗?
  • 如果是 HTTPS,除了 TCP 握手,还需要什么握手?
  • 页面中的图片、CSS、JS 文件需要分别建立连接吗?(想想 HTTP/1.1 的 Keep-Alive)

💡 思考方向

DNS查询通常用UDP(不需要三次握手)。访问百度至少需要1次TCP三次握手(连接Web服务器443端口),HTTPS还需要TLS握手。HTTP/1.1的Keep-Alive复用TCP连接,不需要对每个资源都重新握手。HTTP/2可以多路复用,一个连接传输所有资源。

5

三次握手有延迟代价(至少1.5个RTT),有没有办法减少这个延迟?

提示:了解这些技术——

  • TCP Fast Open(TFO)是什么?它怎么在第一次握手就携带数据?
  • QUIC 协议(HTTP/3)为什么能做到 0-RTT 连接?
  • 这些"加速"方案有没有安全风险?

💡 思考方向

TCP Fast Open在首次连接时服务器发给客户端一个Cookie,之后客户端可在SYN中携带数据+Cookie,服务器验证Cookie后直接处理数据。QUIC基于UDP,将传输和加密握手合并,首次连接只需1-RTT,后续可0-RTT。但0-RTT存在重放攻击风险,需要额外防护。

👨‍🏫 教学建议

题目1-3:基础思考题,适合个人独立完成(5分钟)

题目4:综合应用题,建议2-3人小组讨论(8分钟)

题目5:拓展提升题,适合课后探索或翻转课堂

📋 本课小结

1

TCP特点:面向连接、可靠传输、流量控制、拥塞控制。

2

三次握手:SYN → SYN+ACK → ACK,建立双向连接并同步序号。

3

四次挥手:FIN → ACK → FIN → ACK,全双工两个方向分别关闭。

4

拥塞控制:慢启动→拥塞避免→快重传→快恢复,动态调整发送速率。