🔌 第二章 用电信号传输TCP/IP数据
📄 一句话概括

write 只是把数据放进 TCP 发送缓冲——协议栈按【够一块就发】的规则切块加头出门;write 返回不代表对面收到。

📝 本节和前面几节的关系

第一章的请求消息此刻才真正开始旅行;本篇看它怎么进协议栈。

一、缓冲区的角色

应用程序 write 的数据先进发送缓冲区; 协议栈攒够一块(约 MSS)或收到推送标记才发—— 避免为 10 个字节跑一趟全套流程。

二、write 返回的含义

只代表【数据进了本端缓冲】—— 对面收没收到,要靠 2.3.3 的 ACK 对账。

三、动手 Demo:把消息交给协议栈

数据进站路线:

for s in ['应用程序: write(3, msg, 1500)',
          '  | 进 TCP 发送缓冲区',
          '  v',
          'TCP: 攒够一块 -> 切块加 TCP 头',
          'IP: 加 IP 头 -> 驱动加 MAC 头 -> 出门']:
    print(s)

实跑输出:

--------------------------------------------------------------------
把消息交给协议栈
--------------------------------------------------------------------
  应用程序 write 一条 1500 字节请求后:

    应用程序: write(3, msg, 1500)
        |  数据进 TCP 发送缓冲区
        v
    TCP: 够发了(超过 MSS)或推 urgent -> 切块加 TCP 头
        v
    IP: 加 IP 头 -> 网卡驱动加 MAC 头 -> 出门

  write 返回只代表【进了本端缓冲】,不代表对面收到。

【攒一批再发】和【攒满窗口再发】(2.3.5)是两码事: 前者省开销,后者提吞吐。

30 秒实验

  1. 写 Python 本机回环发 1 字节,用 Wireshark 看实际包多大。
  2. 找找 Nagle 算法的开关(TCP_NODELAY)。
  3. 想想聊天软件为什么要关 Nagle(要快不要攒)。

常见误区

  1. 以为 write 返回即送达——只进了本端缓冲。
  2. 以为协议栈来一个字节发一个包——攒够一块才走。
自测三问(点开对答案) 1. write 的数据先去哪? —— TCP 发送缓冲区。 2. 协议栈攒到什么时候才发? —— 约攒满一块(MSS)或收到推送。 3. write 返回代表什么? —— 进了本端缓冲,不代表对面收到。

相关笔记