传输层

5.1 传输层的功能和端口

传输层是通信子网(下三层)和资源子网(上层应用)之间的桥梁,提供**端到端(进程到进程)**的通信服务。

为什么需要传输层? 网络层负责把数据包从一台主机送到另一台主机(主机到主机),但一台主机上可能运行着多个网络应用(浏览器、微信、邮件客户端等)。传输层通过端口号来区分不同的应用进程,确保数据能送到正确的应用程序。

端口号分类

类型 范围 说明
熟知端口 0~1023 固定分配给重要协议,如HTTP=80,FTP=21,SMTP=25
登记端口 1024~49151 需要IANA登记,如MySQL=3306
动态端口 49152~65535 客户端临时使用

常用熟知端口

协议 端口号 传输层
FTP(数据/控制) 20/21 TCP
SSH 22 TCP
Telnet 23 TCP
SMTP 25 TCP
DNS 53 UDP/TCP
HTTP 80 TCP
POP3 110 TCP
HTTPS 443 TCP
DHCP 67/68 UDP

复用和分用

  • 复用:发送方多个应用共用同一个传输层协议发送数据
  • 分用:接收方传输层根据端口号将数据交给不同的应用进程

传输层的两个重要协议

特性 TCP UDP
连接 面向连接 无连接
可靠 可靠传输 不可靠
有序 有序到达 不保证有序
流量控制 有 无
拥塞控制 有 无
开销 大(首部20B) 小(首部8B)
应用 HTTP、FTP、SMTP、SSH DNS、DHCP、视频通话、直播

5.2 UDP协议

UDP特点

  1. 无连接——发送数据前不需要建立连接,减少了时延
  2. 不可靠——不保证数据到达,不重传丢包
  3. 面向报文——应用层交下来的报文,UDP原封不动地加上首部发送,不拆分也不合并
  4. 首部开销小——只有8字节
  5. 支持一对一、一对多、多对一、多对多通信

UDP首部格式(8B)

源端口(2B) 目的端口(2B) UDP长度(2B) UDP校验和(2B)
  • 源端口:可选,不需要时填0
  • 目的端口:必须填写
  • UDP长度:首部+数据的长度(字节)
  • UDP校验和:可选(IPv4中可选,IPv6中强制)

UDP校验和计算

  • 计算时加上伪首部(12B,包含源IP、目的IP、协议号、UDP长度)
  • 伪首部只用于校验,不传输
  • 计算方式:将数据和伪首部每16位一组,求和取反

5.3 TCP协议

TCP特点

  1. 面向连接——传输前先建立连接
  2. 可靠传输——无差错、不丢失、不重复、按序到达
  3. 面向字节流——把应用层的数据看成字节流,TCP自己决定如何分段
  4. 全双工通信——双方可以同时发送和接收
  5. 流量控制和拥塞控制

TCP首部格式(固定20B)

偏移(bit) 字段 长度(bit) 说明
0 源端口 16
16 目的端口 16
32 序号 32 本报文段数据第一个字节的编号
64 确认号 32 期望收到对方下一个报文段的第一个字节序号
96 数据偏移 4 首部长度,单位4B,最小值5
100 保留 6
106 标志位 6 URG/ACK/PSH/RST/SYN/FIN
112 窗口 16 接收窗口大小,用于流量控制
128 校验和 16 含伪首部
144 紧急指针 16 URG=1时有效
160 选项 可变 MSS、窗口缩放、时间戳等

TCP标志位(重点!)

标志 全称 含义
URG Urgent 紧急指针有效
ACK Acknowledgment 确认号有效(建立连接后一直为1)
PSH Push 立即将数据推送给应用层
RST Reset 复位连接(连接异常时使用)
SYN Synchronize 同步序号,建立连接时使用
FIN Finish 释放连接

序号和确认号(重点!)

  • 序号:本报文段中数据第一个字节的编号
  • 确认号:期望收到的下一个字节的序号
  • 确认号 = 对方最后一个序号 + 对方发送的数据长度
  • 如果对方只发了SYN或FIN(不含数据),确认号 = 序号 + 1

5.4 TCP的连接管理——三次握手

为什么是三次握手? 三次握手是为了确保双方的发送能力和接收能力都正常,并同步初始序号。

三次握手过程

客户端                         服务器
  |                              |
  | ---- SYN=1, seq=x --------> |  第一次:客户端发SYN
  |                              |  客户端进入SYN-SENT状态
  | <--- SYN=1, ACK=1, seq=y,   |  第二次:服务器发SYN+ACK
  |       ack=x+1 -------------- |  服务器进入SYN-RCVD状态
  |                              |
  | ---- ACK=1, seq=x+1,   ---> |  第三次:客户端发ACK
  |       ack=y+1                |  客户端和服务器都进入ESTABLISHED状态

每一步的状态变化

步骤 客户端状态 服务器状态
初始 CLOSED LISTEN
第一次后 SYN-SENT LISTEN
第二次后 SYN-SENT SYN-RCVD
第三次后 ESTABLISHED ESTABLISHED

典型例题

例1:主机A向主机B建立TCP连接,A的初始序号为1000,B的初始序号为5000。写出三次握手的序号和确认号。

解:

  • 第一次:A→B,SYN=1,seq=1000
  • 第二次:B→A,SYN=1,ACK=1,seq=5000,ack=1001(收到A的1000,期望下一个是1001)
  • 第三次:A→B,ACK=1,seq=1001,ack=5001

5.5 TCP的连接管理——四次挥手

四次挥手过程

客户端                         服务器
  |                              |
  | ---- FIN=1, seq=u -------> |  第一次:客户端发FIN(不再发送数据)
  |                              |  客户端进入FIN-WAIT-1状态
  | <--- ACK=1, seq=v,     --- |  第二次:服务器确认
  |       ack=u+1               |  服务器进入CLOSE-WAIT状态
  |                              |  客户端进入FIN-WAIT-2状态
  | <--- FIN=1, ACK=1, seq=w, |  第三次:服务器发FIN(服务器也发完了)
  |       ack=u+1              |  服务器进入LAST-ACK状态
  |                              |
  | ---- ACK=1, seq=u+1,   --> |  第四次:客户端确认
  |       ack=w+1               |  客户端进入TIME-WAIT状态(等待2MSL)

为什么是四次而不是三次? 因为服务器收到FIN后,可能还有数据要发送,所以先发ACK确认,等数据发完再发FIN。两次挥手之间可能有时间间隔。

为什么TIME-WAIT需要等待2MSL?

  1. 确保服务器的ACK超时重传能被客户端正确处理
  2. 防止旧的连接数据干扰新连接

💡 记忆技巧:三次握手像打电话——"喂?"(SYN)、"嗯,我在"(SYN+ACK)、"好,说正事"(ACK)。四次挥手像告别——"我先挂了"(FIN)、"好的"(ACK)、"我也挂了"(FIN)、"拜拜"(ACK)。

5.6 TCP可靠传输

TCP通过以下机制实现可靠传输:

序号机制

  • 每个字节都有序号
  • 首部中的序号是数据第一个字节的序号

确认机制

  • 累积确认:TCP只确认已连续收到的最大序号
  • 接收方收到乱序的报文段会缓存但不确认(等待缺失的部分到达)
  • 通常使用延迟确认(等一段时间,如果有数据要发就捎带确认)

重传机制

  • 超时重传:发送方启动计时器,超时未收到ACK就重传
  • 快速重传:收到3个相同确认(冗余ACK)就立即重传,不等超时

5.7 TCP流量控制

滑动窗口机制

TCP通过**接收窗口(rwnd)**进行流量控制。接收方在TCP首部的窗口字段中告知对方自己的接收能力,发送方的发送窗口不能超过接收窗口的大小。

  • 接收窗口 = 接收缓存大小 - (已收到的数据 - 已读取的数据)
  • 发送窗口 = min(拥塞窗口cwnd, 接收窗口rwnd)

零窗口

  • 当接收方窗口为0时,发送方停止发送
  • 发送方启动持续计时器,到期后发送零窗口探测报文
  • 接收方回复窗口大小,如果还是0,发送方重新设置持续计时器

5.8 TCP拥塞控制(重点!)

拥塞控制 vs 流量控制

  • 流量控制:防止"快发慢收"(接收方缓存溢出)
  • 拥塞控制:防止"发得太快导致网络拥堵"(路由器缓存溢出)

四个算法

TCP拥塞控制包括:慢开始、拥塞避免、快重传、快恢复。

慢开始(Slow Start)

  • 初始cwnd = 1 MSS(最大报文段长度)
  • 每收到一个ACK,cwnd增加1 MSS
  • 指数增长:1 → 2 → 4 → 8 → ...
  • 当cwnd ≥ ssthresh(慢开始门限)时,转入拥塞避免

拥塞避免(Congestion Avoidance)

  • 每经过一个RTT,cwnd增加1 MSS(而不是每收到一个ACK)
  • 线性增长:避免了指数增长导致的过快拥塞

快重传(Fast Retransmit)

  • 发送方连续收到3个对同一序号的冗余ACK
  • 不等超时,立即重传丢失的报文段

快恢复(Fast Recovery)

  • 与快重传配合使用
  • 将ssthresh = cwnd / 2
  • 将cwnd = ssthresh + 3(有些实现直接设为ssthresh)
  • 直接进入拥塞避免阶段

发生超时时

  • ssthresh = cwnd / 2(至少为2)
  • cwnd = 1
  • 重新进入慢开始阶段

典型例题

例2:一个TCP连接,MSS=1KB,初始ssthresh=16KB。请写出从慢开始到拥塞避免的cwnd变化过程(直到cwnd=24KB时出现3个冗余ACK)。

解:

慢开始阶段:

  • RTT 1:cwnd = 1,发送1个,收到ACK后 → cwnd = 2
  • RTT 2:cwnd = 2,发送2个,收到ACK后 → cwnd = 4
  • RTT 3:cwnd = 4 → 8
  • RTT 4:cwnd = 8 → 16 (达到ssthresh=16)
  • RTT 5:cwnd = 16 → 进入拥塞避免,cwnd = 17

拥塞避免阶段:

  • RTT 6:cwnd = 18
  • RTT 7:cwnd = 19
  • RTT 8:cwnd = 20
  • RTT 9:cwnd = 21
  • RTT 10:cwnd = 22
  • RTT 11:cwnd = 23
  • RTT 12:cwnd = 24(此时收到3个冗余ACK)

快重传+快恢复:

  • ssthresh = 24/2 = 12
  • cwnd = ssthresh + 3 = 15(有些实现设为12)
  • 进入拥塞避免阶段

拥塞控制整个过程总结

cwnd
  ^
  |  慢开始        拥塞避免
24 |               \            (收到3冗余ACK)
   |                 \
16 |     \             \
   |       \            \
 8 |         \            \
   |           \            \
 4 |             \            \
   |               \            \
 1 |                 \            \
   +-----------------------------------> RTT
     1  2  3  4  5  6  7  8  9 10 11 12
事件 新ssthresh 新cwnd 后续阶段
超时 cwnd/2 1 慢开始
3个冗余ACK(快重传) cwnd/2 ssthresh+3(或ssthresh) 拥塞避免

📌 408考点提示:拥塞控制是必考题型!

  1. 给初始值,要求写出每个RTT的cwnd变化
  2. 判断某个时刻处于什么阶段
  3. 区分超时和冗余ACK时的不同处理

⚠️ 易错点:

  1. 慢开始每收到一个ACK加1,不是每个RTT加1(增长是指数级的)
  2. 拥塞避免每RTT加1(线性增长)
  3. 快恢复不是"从0开始",而是直接从ssthresh开始线性增长
  4. cwnd和rwnd的最小值决定实际的发送窗口

5.9 TCP定时器

定时器 用途 说明
超时计时器 重传超时 发送一个报文段就启动,收到ACK后取消
持续计时器 零窗口探测 收到零窗口通知后启动,防止死锁
保活计时器 检测死连接 长时间无数据交换时,探测对方是否存活
时间等待计时器 TIME-WAIT 四次挥手中等待2MSL

RTO(重传超时时间)的计算

  • RTO基于RTT(往返时间)估算
  • 自适应算法:根据当前网络状况动态调整
  • 标准方法:RTO = SRTT + 4 × RTTvar

5.10 传输层核心总结

知识点 关键内容
端口 熟知(0-1023)、登记(1024-49151)、动态(49152-65535)
UDP 无连接、不可靠、8B首部、面向报文
TCP 面向连接、可靠、20B首部、面向字节流
三次握手 SYN→SYN+ACK→ACK,同步序号
四次挥手 FIN→ACK→FIN→ACK,2MSL等待
流量控制 滑动窗口、rwnd
拥塞控制 慢开始、拥塞避免、快重传、快恢复

端口速记表

端口 协议
20/21 FTP
22 SSH
23 Telnet
25 SMTP
53 DNS
67/68 DHCP
80 HTTP
110 POP3
443 HTTPS

💡 记忆技巧:应用层协议端口号——"FTP是20、21,SSH是22,Telnet是23,SMTP是25,DNS是53,HTTP是80"。可以按数字顺序记:20/21(FTP)→22(SSH)→23(Telnet)→25(SMTP)→53(DNS)→80(HTTP)。

综合例题

例3:一个TCP连接使用慢开始,初始cwnd=1,ssthresh=16,在第4个RTT结束时检测到超时。求: (1)第5个RTT开始时cwnd和ssthresh的值 (2)第6个RTT结束时cwnd的值 (3)第8个RTT结束时cwnd的值

解:

RTT过程:

  • RTT1结束:cwnd=2,ssthresh=16
  • RTT2结束:cwnd=4,ssthresh=16
  • RTT3结束:cwnd=8,ssthresh=16
  • RTT4结束:cwnd=16(达到ssthresh),超时!

(1)第5个RTT开始时:

  • ssthresh = 16/2 = 8
  • cwnd = 1(超时后从1重新开始)
  • 进入慢开始

(2)第6个RTT结束时:

  • RTT5:cwnd=1→2(慢开始)
  • RTT6:cwnd=2→4(慢开始,还没到ssthresh=8)
  • 第6个RTT结束时cwnd=4

(3)第8个RTT结束时:

  • RTT7:cwnd=4→8(慢开始,cwnd达到ssthresh=8)
  • RTT8:cwnd=8→9(拥塞避免,线性增长+1)
  • 第8个RTT结束时cwnd=9