高级 #network#tcp#reliable

TCP 三次握手与可靠传输

TCP(Transmission Control Protocol)是互联网最核心的传输协议——通过三次握手建立连接、序列号保证顺序、确认和重传保证可靠,让不可靠的 IP 网络变成可靠的通信通道

把不可靠的网络变可靠

IP 层是”尽力而为”的——包可能丢失、乱序、重复。TCP 在 IP 之上增加了可靠性:让乱序的数据重新排序、让丢失的包重传、让重复的包去重。

🏫 类比:寄挂号信 vs 平信 UDP(平信):写了地址就寄出去——丢了不负责。 TCP(挂号信):寄出前确认你能收、每封信有编号(序列号)、收件人要签收确认(ACK)、没收到就重寄。

TCP 包头

 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
┌───────────────┬───────────────────────────────────────────────┐
│ 源端口        │ 目标端口                                      │
├───────────────┼───────────────────────────────────────────────┤
│ 序列号(Sequence Number)                                    │
├───────────────────────────────────────────────────────────────┤
│ 确认号(Acknowledgment Number)                              │
├───────┬───────┬───────────────────────────────────────────────┤
│ 偏移  │ 保留  │U│A│P│R│S│F│  窗口大小(Window Size)         │
├───────┴───────┴───────────────────────────────────────────────┤
│ 校验和          │ 紧急指针                                    │
├───────────────────────────────────────────────────────────────┤
│ 选项(可选)                                                  │
└───────────────────────────────────────────────────────────────┘

三次握手(Three-Way Handshake)

TCP 建立连接需要三次消息交换:

客户端                         服务器
  │                              │
  │ 1. SYN (seq=x)               │
  │ ──────────────────────────→ │
  │                              │
  │ 2. SYN+ACK (seq=y, ack=x+1) │
  │ ←────────────────────────── │
  │                              │
  │ 3. ACK (seq=x+1, ack=y+1)   │
  │ ──────────────────────────→ │
  │                              │
  │      连接建立完成             │
  │      开始传输数据             │
# 用 tcpdump 观察三次握手
$ tcpdump -nn -i eth0 host 192.168.1.1 and port 80

14:23:01.123 IP 192.168.1.1.54321 > 203.0.113.1.80: S 1000:1000(0) win 65535
14:23:01.124 IP 203.0.113.1.80 > 192.168.1.1.54321: S 2000:2000(0) ack 1001 win 65535
14:23:01.124 IP 192.168.1.1.54321 > 203.0.113.1.80: . ack 2001 win 65535

💡 三次握手的核心目的:客户端确认自己→服务器通路和服务器→客户端通路都正常。同时双方交换初始序列号。

可靠传输机制

序列号

每个字节的数据都有一个序列号——接收方用序列号把数据排回正确的顺序。

发送方发:
[seq=1, 100字节]   → 确认(ack=101)
[seq=101, 100字节] → 确认(ack=201)
[seq=201, 100字节] → 丢失!→ 超时重传
[seq=201, 100字节] → 重传 → 确认(ack=301)

确认与重传

发送方发完数据后启动定时器——如果在超时前收到 ACK,说明数据到达;如果超时未收到 ACK → 重传。

# TCP 发送方简化逻辑
def tcp_send(data):
    seq = next_seq()
    send_packet(seq, data)
    start_timer()
    
    while not acknowledged(seq):
        if timer_expired():
            # 超时——重传
            # 指数退避(下次超时翻倍)
            timeout *= 2
            send_packet(seq, data)
            restart_timer()

快速重传

如果接收方收到乱序的包——立即重复确认(DupACK)。发送方收到 3 次重复确认 → 立即重传(不等超时)。

发送方           接收方
   │              │
   │ [seq=1]     →│ 正常收到,ack=2
   │ [seq=2]      │ 丢了!
   │ [seq=3]     →│ 乱序!ack=2(DupACK #1)
   │ [seq=4]     →│ 乱序!ack=2(DupACK #2)
   │ [seq=5]     →│ 乱序!ack=2(DupACK #3)
   │               │
   │← 3 次 DupACK │
   │ [seq=2] 重传 │

四次挥手(连接关闭)

客户端                         服务器
  │                              │
  │ 1. FIN                      │
  │ ──────────────────────────→ │
  │                              │  ← 服务器可能还在发数据
  │ 2. ACK                      │
  │ ←────────────────────────── │
  │                              │
  │ 3. FIN                      │(服务器发完数据后)
  │ ←────────────────────────── │
  │                              │
  │ 4. ACK                      │
  │ ──────────────────────────→ │
  │                              │
  │      连接关闭                │

小结

概念要点
三次握手SYN → SYN+ACK → ACK 建立连接
序列号为每个字节编号,保证有序性
确认+重传超时或三次 DupACK 触发重传
四次挥手FIN → ACK → FIN → ACK 关闭连接
有状态两端都需要维护连接状态

为什么先学这个? TCP 的可靠传输机制是互联网的基石。下一节看看TCP 流量控制与拥塞控制——TCP 如何避免发送太快把网络”塞爆”。