悟夕导航

【TCP/IP 教程·第八弹】《TCP 三次握手:处女座外卖员的爱情协议》

64 0 0
上回用 Ping+Traceroute 把雷达踩个遍,今天啃硬货——TCP 握手
它像处女座外卖员:先电话确认、再敲门、还要你签字,
少一步就原地重传,堪称网络界“强迫症患者”。

1. 报文格式:20 字节固定头 + 选项

0                   1                   2                   3
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Source Port          |       Destination Port        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Sequence Number                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Acknowledgment Number                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  HL  |  |U|A|P|R|S|F|       Window Size                       |
|      |R |R|C|S|S|Y|I|                                        |
|      |C |G|K|H|T|N|N|                                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           Checksum            |         Urgent Pointer        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • Seq = 自己的序号
  • Ack = 对方序号 + 1(确认)
  • SYN/FIN/ACK/RST = 各种“情绪开关”
记不住?把 SYN 想成“Seek You”,FIN 想成“Finish”。

2. 三次握手:相亲现场

Client: SYN=1, Seq=x          →    “我可以约你吗?”
Server: SYN=1, ACK=1, Seq=y, Ack=x+1 → “可以,我也单身。”
Client: ACK=1, Ack=y+1        →    “好,那我不鸽。”

完成!双向序号同步 + 双向确认
任何一步丢包都重传,比民政局还严谨


3. 为什么不是两次?

假设只有两次:

  • Client 发 SYN,Server 回 SYN+ACK,完事
  • Client 的 SYN 如果超时重传,Server 收到旧 SYN
    以为新连接,建立脏连接→浪费资源
第三次 ACK 就是“我活着”证据,
杜绝历史连接+同步初始序号,专业术语:防止“旧的重复报文”

4. 同时打开:罕见“双向暗恋”

两边同时发 SYN,交叉确认
只需要 2 次报文就能建连,
抓包会出现 SYN+ACK 同一条报文
像两人同时说“我喜欢你”,爱情加速


5. 四次挥手:离婚分家产

Client: FIN=1, Seq=m          →    “我想离。”
Server: ACK=1, Ack=m+1       →    “知道了。”
Server: FIN=1, Seq=n          →    “我东西收完了。”
Client: ACK=1, Ack=n+1       →    “拜拜。”
  • 中间两次不能合并(TCP 全双工,双向独立
  • 最后 ACK 发完,等 2MSL(Linux 60 s)才释放,
    防止最后 ACK 丢失,对方重传 FIN 无人回。

6. 半连接队列与 SYN Flood

Server 收到 SYN,回复 SYN+ACK,
此时连接处于 SYN-RCVD,放半连接队列(默认 1024)。
黑客伪造源 IP 发海量 SYN → 队列塞满 → 正常用户握手失败

防御

  • SYN Cookies:不分配资源,把序号加密到 Seq,
    等第三次 ACK 带回来再建连(Linux 默认开)
  • 缩短 SYN Timeout
  • 防火墙限流 + 黑名单

7. 快速重传 & 快速恢复

3 个重复 ACK → 立即重传丢失段,不用等超时
像外卖员连收 3 条“珍珠没放”,立马回头重做,
然后降窗→线性增,进入“快速恢复”。


8. MSS 与 MTU:面包片大小

握手时双方互报 MSS(Max Segment Size),
常见 1460 = 1500 MTU - 20 IP - 20 TCP。
如果中间链路 MTU=1492(PPPoE),会被分片 → 性能掉。

发现分片,立刻 Path MTU Discovery,把 DF 置位
收到 ICMP 3/4 就降 MSS,避免分片,让数据跑得更丝滑。

9. 状态转换图:恋爱到分手

CLOSED → SYN_SENT → ESTABLISHED → FIN_WAIT_1 → FIN_WAIT_2 → TIME_WAIT → CLOSED
                      ↑                ↓
                   SYN_RCVD        CLOSE_WAIT
                      ↓                ↓
                   ESTABLISHED → LAST_ACK → CLOSED
背不下?记住“两个 ESTABLISHED 是热恋,TIME_WAIT 是冷静期”

10. 排障口诀

握手失败看半连接:netstat -an | grep SYN
重复 ACK 超 3 个 → 快速重传
FIN 不掉 → CLOSE_WAIT 程序没 close()
TIME_WAIT 过多 → 缩短 2MSL 或复用端口
MSS 太大被分片 → 开 Path MTU
Linux 调参三件套:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_syn_backlog = 8192

下集预告

第九弹《UDP & TCP 对比:渣男 vs 处女座》

  • 无连接 vs 面向连接
  • 报文边界 vs 字节流
  • 拥塞控制、重传、顺序,谁管?
  • 视频卡了,为什么 UDP 不重传?
  • QUIC 如何把 UDP 变成“可重传的渣男”?

关注不迷路,下回继续开炮!

0
快来点个赞吧

发表评论

隐私评论

评论列表

来写一个评论吧