🌐 第三章 网络间的通用语言TCP/IP
📄 一句话概括

IP 是网际层的"寄件规则",它干两件事:给包写上门牌(源/目的 IP)和决定往哪送(路由)。路由器靠肚子里的路由表回答"下一跳交给谁",一站站接力;包身上的 TTL 每过一跳减 1,减到 0 就销毁——保证包不会在网络里永远打转。

一、先给 IP 摆正位置

3.1 说过,TCP/IP 家族的两位冠名明星是 TCP 和 IP。3.3 讲了 TCP(保达:确认、重传、按序),本节轮到另一位主角。

分工一句话:

TCP 管"到底送到没送到",IP 管"往哪个方向送"。

IP 的两大职责:

  1. 编址——给每台联网设备一个门牌(1.2 那两套号:私有 IP 和公网 IP)
  2. 路由——给每一个包决定下一步往哪儿走
💡 收 3.2 的旧账

3.2 说网际层"管全程、看 IP 门牌"。本节把这句话拆成了具体动作:写门牌 = 填 IP 头,"管全程" = 一路逐跳选路。

二、IP 数据包:门牌和规矩都写在头上

3.6 给这一层的东西起了名——数据包(Packet)。本节把它的头拆开看(对应上面第一张图):

首部字段 装什么 干什么用
版本 4 还是 6 用哪套门牌规矩(IPv4 / IPv6)
总长度 整包多少字节 对端知道这次该收多长
标识 / 标志 / 分片偏移 分片三兄弟 认亲 + 拼装:这些片是不是一家、后面还有没有、这片在原文里排第几(3.4 的分片全靠它们)
TTL 还能走几跳 每过一跳减 1,减到 0 丢弃(见第四点)
协议 里面装的是谁的东西 6 = TCP、17 = UDP、1 = ICMP(ping 用它)
首部校验和 头部有没有被路上改坏 只管头部;数据归 TCP 的校验和管(分层各管一段)
源 IP / 目的 IP 门牌 全程不变(3.2 说的"IP 头端到端不变")

关键认知:源 IP 和目的 IP 是整张头部里唯二"全世界通用"的信息——沿途哪怕十几台路由器,做的决定全部基于"目的 IP 是多少";其余字段都是留给收发两端自己看的。

三、路由:包怎么被一站站送到

路由 = 选路,干这活的设备是路由器(2.2 说它"看地图",那张地图就是路由表)。

路由表的结构很朴素——一行 = 目标网段 → 下一跳(对应上面第二张图)。

路由器查表时守三条规矩:

  1. 最长前缀匹配:越具体的条目越优先。地址本上同时记着"张伟"和"张伟 · 三班",找三班的当然翻后者
  2. 默认路由 0.0.0.0/0 兜底:所有不认识的,统统交给上级网关。家里路由器就靠"自家网段直连 + 其他全给运营商",一张小表通全网
  3. 逐跳独立决策:每台路由器只管自己这一步,不掌握也不需要掌握全程(1.4 的逐跳接力,本节看到了它的实现)

还有一层区分(会认就行):

💡 为什么说路由器"只知道下一跳"

因为它手上只有本机那一张路由表。表里从来没有"从你家到百度全程怎么走",只有"往这个方向走、交给谁"。路是每台路由器各回答一句问出来的,不是谁事先规划好的。

四、TTL:包身上的保质期

为什么需要它:网络里可能出现环路——A 认为该交给 B,B 又认为该交给 A,包会一直转下去,把线路占满。TTL 就是给这种情况上的保险。

顺带一个结果——tracert 就是靠这条规矩工作的:依次发 TTL = 1、2、3…… 的包。TTL=1 时第一台路由器把它扔掉、顺手暴露自己;TTL=2 时第二台暴露自己……一路点名,路线就凑出来了(收 1.3、1.4 的 tracert)。

💡 名字叫"生存时间",为什么按跳数算

名字是历史遗留(早期确实按秒算)。现在实际执行的规矩,准确的叫法是 Hop Limit(跳数上限)——还剩几跳。

五、一次完整的发送和接收(把 3.1~3.6 串一遍)

步骤 谁在动手 干了什么 出自
1 应用层 程序写好要发的内容 3.3
2 传输层 切段、加 TCP 头(端口、序号、窗口) 3.3 / 3.4
3 网际层 加 IP 头(源 / 目的 IP、协议、TTL) 本节
4 网络接口层 加帧头帧尾,网卡发出去 3.2
5 第一台路由器 脱帧头 → 读目的 IP → 查表 → TTL 减 1 → 换新帧头送下一跳 本节
6 中间每一跳 重复第 5 步,直到到达目标所在的网络 1.4
7 目标机器 自下而上逐层脱信封:看协议号决定交给 TCP 还是 UDP → 按序号重组 → 程序拿到原文 3.5 / 3.6

一句话总结这三层的分工:IP 头负责"走完全程",帧头负责"走完一段",TTL 负责"别走没完"。

六、动手 Demo21:把路由表和 TTL 亲手摸一遍

  1. 打开命令行(Win+R → cmd)

  2. 读自家的路由表(3.2 见过一次,这回看得懂它): route print -4

  3. 主要看三列:网络目标 / 网关 / 接口
  4. 带 On-link(直连)的行 = 同一个网段里的邻居,自己直接送
  5. 找 0.0.0.0 那一行 = 默认路由,它后面的网关就是你家的出门口(1.2 的总机、1.3 的默认网关,在此正式落脚)

  6. 亲手让 TTL 撞墙: ping -i 1 www.baidu.com

  7. 应该报「TTL 传输中过期」——包刚出第一跳就被扔了,连门都没出去 ping -i 2 www.baidu.com
  8. 走得远一点,大概率仍然过期 ping -i 8 www.baidu.com
  9. 这回多半能通。你其实刚刚手工做了一次 tracert
  10. ⚠️ 参数别记串:Windows 下 -i 后面跟 TTL 值;Linux 下设 TTL 是 -t(-i 在 Linux 里是发包间隔)

  11. 30 秒实验:从返回的 TTL 猜跳数

  12. ping 127.0.0.1 → 返回 TTL=128(本机,Windows 的默认初值,一跳都没走)
  13. ping www.baidu.com → 返回的 TTL 会明显小(常见 50 上下)
  14. 估算方法:对方初始 TTL − 你看到的 TTL ≈ 经过的跳数。如果百度那台是 Linux 主机(初值 64),看到 52 就是约 12 跳
  15. 拿 tracert www.baidu.com 数出来的跳数对一下,两者大致吻合
  16. 提醒:这只是估算——对方的初值到底是 64、128 还是 255,你事先并不知道;要数得准,还是直接 tracert

  17. 可选:ping 一个国外站点,返回的 TTL 更小、延迟更大——路更长,收 1.4 那个"越远越慢"的体感。

❓ 自测一下
  1. IP 在通信里负责哪两件事?它和 TCP 怎么分工?
  2. IP 头里的"分片三兄弟"是哪三个字段?为什么需要三个而不是一个?
  3. TTL 干什么用?减到 0 会怎样?tracert 靠它实现了什么?
  4. 路由表里的 0.0.0.0/0 是什么意思?为什么家里路由器只有那么几行就能通全网?
  5. 为什么"最长前缀匹配"这条规矩是必须的?

答案: ① 编址(给设备写门牌)+ 路由(给包选路线);TCP 管"可靠送达"(确认、重传、按序),IP 只管"尽力而为地往哪送"。 ② 标识 + 标志 + 分片偏移。一个字段不够用:标识用来认亲(哪些片原是一家),标志告诉对端后面还有没有片,分片偏移说明这片在原文里排第几——三样齐了才拼得回原文。 ③ 限制包最多能走几跳,每过一跳减 1,减到 0 被当场销毁并回 ICMP 超时;tracert 依次发 TTL = 1、2、3…… 的包,用每台路由器"扔掉它时回的那句话"把沿途每一跳点名。 ④ 默认路由:兜底条目,"我不认识的全交给它"。家里的路由器知道"自家网段直连"+"其余交给运营商网关",剩下的交给运营商的路由器继续接力。 ⑤ 因为表里可能同时存在大范围和小范围的条目(/16 和 /24)。不按"越具体越优先",选择就不唯一,包可能被送错方向——越精确的条目越贴近真实目的地。

常见误区:

  1. ❌ "IP 保证数据一定送到" → IP 只尽力而为,丢了不补;可靠性是 TCP 补出来的(收 3.2 埋的那个坑)
  2. ❌ "路由器知道全世界的完整路线" → 每台路由器只有自己那张表,路是逐跳问出来的(1.4)
  3. ❌ "TTL 是按秒算的生存时间" → 实际按跳数算,学名 Hop Limit(跳数上限)
  4. ❌ "路由表是写死的" → 会随网络变化自动更新(动态路由);断线、拥堵都可能让它改路
  5. ❌ "ping 不通就是网络断了" → 也可能是对方禁 ping、或防火墙把 ICMP 丢了(2.4 埋过这个坑)
  6. ❌ "IP 头里的校验和能保证数据没被改坏" → 它只校验头部;数据完整性归 TCP 的校验和管(3.4)

七、下一步学什么

相关笔记