专栏文章
专栏文章
网络协议专栏
1. 网络协议专栏 #01:TCP/IP 协议栈 2. 网络协议专栏 #02:HTTP 协议 3. 网络协议专栏 #03:HTTPS 与 TLS 4. 网络协议专栏 #04:网络编程速查

网络协议专栏 #01:TCP/IP 协议栈

发布于 2026-06-08 07:51 👁 7 次阅读
#TCP#udp#network#ip

本文覆盖 OSI 与 TCP/IP 分层模型对比、IP 协议基础、TCP 三次握手/四次挥手完整状态机、TCP 可靠性机制(序号/确认/重传/滑动窗口/流量控制/拥塞控制),以及 UDP 特性与 TCP/UDP 选型。


目录

章节 说明
OSI vs TCP/IP 分层模型 两种模型对比
IP 协议 子网划分、路由、CIDR
TCP 三次握手 每步状态与原因
TCP 四次挥手 每步状态与 TIME_WAIT 原因
TCP 可靠性机制 序号/确认/重传/滑动窗口/流量控制/拥塞控制
UDP 特性与适用场景 UDP 核心特性
TCP vs UDP 选型 选型对比表

OSI vs TCP/IP 分层模型

层次 OSI 7 层 TCP/IP 4 层 代表协议
7 应用层 应用层 HTTP、HTTPS、DNS、FTP
6 表示层 应用层 TLS/SSL
5 会话层 应用层
4 传输层 传输层 TCP、UDP
3 网络层 网络层 IP、ICMP、ARP
2 数据链路层 网络接口层 Ethernet、Wi-Fi
1 物理层 网络接口层 网线、光纤

核心原则:只要是在网络上跑的包,都是完整的。可以有下层没上层,绝对不可能有上层没下层。每一层的数据在发送时向下封装头部,接收时向上剥离头部。

二层/三层设备的本质:都是运行在其上的程序不同。二层设备(交换机)只摘 MAC 头,三层设备(路由器)摘 MAC 头再摘 IP 头,HTTP 包经过二层设备时,二层设备收到的是包含所有层的完整数据包。


IP 协议

地址结构

IP 地址 = 网络号 + 主机号,通过子网掩码区分。

类别 地址范围 默认子网掩码
A 类 1.0.0.0 – 126.255.255.255 255.0.0.0 /8
B 类 128.0.0.0 – 191.255.255.255 255.255.0.0 /16
C 类 192.0.0.0 – 223.255.255.255 255.255.255.0 /24

CIDR 无类域间路由

格式:192.168.1.0/24,斜线后数字表示网络位长度。

192.168.1.0/24
  网络地址:192.168.1.0
  广播地址:192.168.1.255
  可用主机:192.168.1.1 – 192.168.1.254(共 254 个)

路由转发


TCP 三次握手

TCP 三次握手的目标:双方确认各自的发送和接收能力均正常,并协商初始序列号(ISN)。

tcp three way handshake

sequenceDiagram
    participant C as 客户端
    participant S as 服务端
    Note over C: CLOSED
    Note over S: LISTEN
    C->>S: SYN (seq=x)<br/>客户端发起连接
    Note over C: SYN-SENT
    S->>C: SYN+ACK (seq=y, ack=x+1)<br/>服务端确认并发起连接
    Note over S: SYN-RCVD
    C->>S: ACK (ack=y+1)<br/>客户端确认
    Note over C: ESTABLISHED
    Note over S: ESTABLISHED

为什么是三次而不是两次?

两次握手无法让服务端确认"服务端发出的 SYN-ACK 已被客户端收到",即服务端无法确认自己的发送能力和客户端的接收能力。三次握手后双方都完成了"一发一收"的验证。

为什么不是四次?

四次可以,但没有必要。三次已经足以让双方各完成一次"有去有回"的验证,且 TCP 连接建立后客户端会马上发数据,进一步确认连接状态。


TCP 四次挥手

四次挥手原因:TCP 是全双工的,双方各自独立关闭自己方向的连接,所以需要各发一个 FIN。

tcp four way close

tcp state machine

sequenceDiagram
    participant A as 主动关闭方
    participant B as 被动关闭方
    A->>B: FIN (seq=u)<br/>我不再发数据了
    Note over A: FIN_WAIT_1
    B->>A: ACK (ack=u+1)<br/>收到,但我还有数据要发
    Note over A: FIN_WAIT_2
    Note over B: CLOSE_WAIT
    B->>A: FIN (seq=v)<br/>我也不发了
    Note over B: LAST_ACK
    A->>B: ACK (ack=v+1)<br/>收到
    Note over A: TIME_WAIT → 2MSL → CLOSED
    Note over B: CLOSED

TIME_WAIT 存在的两个原因:

  1. 保证最后一个 ACK 能到达 B:若 ACK 丢失,B 会重发 FIN,A 在 TIME_WAIT 期间可以重新发 ACK。若 A 直接关闭,B 的重发 FIN 将得不到响应,B 无法正常关闭。

  2. 防止旧连接的数据包污染新连接:A 的端口复用后,旧连接在网络中游荡的数据包可能被新连接误收。等待 2MSL(Maximum Segment Lifetime,报文最大生存时间,通常为 30s~2min)可确保旧包全部消亡。


TCP 可靠性机制

序号与确认(累计确认)

每个 TCP 包都有序号(Sequence Number),接收方返回确认号(ACK),表示"该序号之前的数据都已收到,期待下一个包"。这种方式叫累计确认(Cumulative Acknowledgment)。

超时重传与快速重传

重传方式 触发条件 特点
超时重传 定时器超期未收到 ACK 超时间隔自适应(RTT 加权平均),每次超时间隔翻倍
快速重传 收到 3 个重复 ACK 不等超时,立即重传丢失包,说明网络状况不算太差
SACK TCP 头扩展字段 接收方告知已收到的非连续数据,发送方精准补发

滑动窗口

发送方维护一个发送缓冲区,分为 4 个区域:

|--- 已发已确认 ---|--- 已发未确认 ---|--- 未发可发 ---|--- 未发暂不发 ---|
                  ↑ LastByteAcked    ↑ LastByteSent   ↑ LastByteAcked+AdvertisedWindow

窗口随 ACK 到来向右滑动,允许批量发送多个包而无需等待每个 ACK。

流量控制

接收方在 ACK 中携带接收窗口大小(rwnd),告知发送方自己当前的处理能力。发送方不能发超出窗口的数据。

拥塞控制

拥塞窗口(cwnd)控制发送速率,防止把网络塞满。实际发送量 = min(cwnd, rwnd)。

阶段 行为 触发条件
慢启动 cwnd 指数增长(每 RTT 翻倍) 连接初始,cwnd=1
拥塞避免 cwnd 线性增长(每 RTT +1) cwnd 超过 ssthresh
快速恢复 cwnd = ssthresh + 3,线性增长 收到 3 个重复 ACK
超时重传 cwnd=1,重新慢启动,ssthresh=cwnd/2 超时

TCP BBR 算法:传统拥塞控制以"丢包"作为拥塞信号,BBR 通过测量带宽和 RTT 来估算最优发送速率,在填满管道的同时不填满缓冲区,实现高带宽低时延。


UDP 特性与适用场景

UDP 头部仅 8 字节(源端口、目标端口、长度、校验和),天然"性善",不做任何可靠性保证。

特性 说明
无连接 不需要建立连接,直接发送
不可靠 不保证送达、不保证顺序、不重传
无流量控制 发多快就多快,不管接收方
低开销 头部小,无握手,延迟低
支持广播/多播 TCP 不支持

适用场景


TCP vs UDP 选型

维度 TCP UDP
可靠性 保证,有重传 不保证
顺序性 保证 不保证
连接 有连接(三次握手) 无连接
延迟 较高(握手+重传)
吞吐量 受拥塞控制限制 无限制
广播/多播 不支持 支持
适用 文件传输、HTTP、数据库 音视频、DNS、游戏

选型原则:对数据完整性要求高、顺序敏感 → TCP;对延迟敏感、允许少量丢失、需要自定义可靠性策略 → UDP。


参考资料

  • 《趣谈网络协议》— 刘超,极客时间,第 2、10、11、12 讲
  • RFC 793 (TCP)、RFC 768 (UDP)、RFC 791 (IP)
← 返回列表

评论 (0)

暂无评论,来留下第一条吧。

发表评论