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

机器只认数字地址(110.242.68.66),人只记得住名字(www.baidu.com)——DNS(域名系统)就是夹在中间的那本电话簿。但要注意:这本簿子不是一本,是全世界上下分层、各管一段的一整套系统。域名要从右往左读:根 → 顶级域 → 二级域 → 主机名,范围由大到小;而查号的过程,是一台"代问员"替你从最顶层一路问到最具体的那台服务器。

📝 本节和 3.12 的分工(别混)

3.12 讲的是"领四件套",DNS 只是四件套里的第四件——它只说了一句"域名去哪查号",顺便点出了"第 3 条 ping 不通而第 2 条通,就是 DNS 的错"。 本节把这一件单独拿出来讲透:电话簿长什么样、谁在翻、怎么翻、翻完记在哪。

📝 本节在第三章里的位置

到 3.20 为止,第三章讲的都是"怎么把数据送到"——地址、路由、端口、TCP/UDP。 本节是第一处"应用程序自己定义的规则":DNS 是应用层协议(收 3.3),它把前面所有机制当成工具,自己干一件业务上的事——把名字翻译成地址。

一、问题从哪来:机器记数字,人记名字

先看两个要打架的需求:

谁 擅长什么 想要什么
机器(路由器、交换机) 处理数字 明确的 IP 地址(110.242.68.66)
人(你) 记名字 好念好写的 域名(www.baidu.com)

要命的是这两边都没法迁就对方:

而且更麻烦的是:网站的 IP 是会变的(换机房、加服务器、上 CDN)。真把 IP 写进你脑子里,它一变你就找不到人了。

❗ 一句话立论

域名是给人用的名字,IP 是给机器用的地址,中间必须有一层翻译。

这层翻译就叫 域名解析(name resolution),干这活儿的系统叫 DNS。

顺带收 3.8 的旧账:IP 跟位置走、不跟机器走。域名正好相反——名字是稳定的,地址可以随便换。这才是域名存在的根本理由:它把"会变的东西"藏在了"不变的名字"后面。

二、先分清三个词:主机名、域名、URL

标题里三个词容易混,先一次分清。

词 是什么 例子 作用范围
主机名(hostname) 一台设备自己的名字 localhost、Windows 里的"计算机名" 常常只在本机或本网段有效,不保证全世界唯一
域名(domain name) 在互联网上通行的名字 www.baidu.com 由 DNS 全球统一解析,同一时刻唯一
URL(网址) 一个完整的访问地址,域名只是其中一小段 https://www.baidu.com/s?wd=abc —

看那张 URL 的拆解就清楚了:

https://www.baidu.com/s?wd=abc
  │         │          │  └── 参数(搜什么)
  │         │          └── 路径(服务器上的哪个位置)
  │         └── 域名 ← 只有这一段归 DNS 管
  └── 协议(用哪种方式谈)

"网址 = 域名"是最常见的混淆(写进了下面的误区表)。DNS 只负责把中间那段翻译成 IP,剩下的交给 HTTP(收 3.3 的应用层名单)。

💡 收 Java 13.1 的旧账

网络基础 里那个 InetAddress 同时出现了这两个词:

InetAddress local = InetAddress.getLocalHost();
System.out.println(local.getHostName());     // ← 主机名(本机的名字)

InetAddress baidu = InetAddress.getByName("www.baidu.com");  // ← 走 DNS 解析
System.out.println(baidu.getHostAddress());  // ← 解析出来的 IP

getHostName() 拿的是主机名,getByName("域名") 走的是域名解析——两件事、两条路。当时只是照着敲,现在知道它背后发生了什么了。

还有那个 UnknownHostException("查无此人")——它对应的正是下面的误区:这条错误不是网络不通,是电话簿里没这个名字。

📝 FQDN:域名其实末尾还有个点

严格写全的域名末尾要加一个点:www.baidu.com.——那个点代表根域,是所有域名的起点。

平时都省略(浏览器会自动补),但偶尔会看到(比如某些配置文件的写法)。认识它,下一节的层级图就一眼看懂了。

三、域名长什么样(本节第一张图)

域名的结构是逐层嵌套的,一共四层:

层级 叫法 例子 说明
第 1 级 根域 .(末尾那个点) 约定的起点,平时省略
第 2 级 顶级域 TLD .com .org .net .cn 分两族:通用顶级域(.com 商业 / .org 组织 / .net 网络)与国家地区顶级域(.cn 中国 / .jp 日本 / .uk 英国)
第 3 级 二级域 baidu 你花钱注册的那一个名字
第 4 级 主机名 / 子域 www mail api 同一个域名下可以有很多台机器,各起各的名

读法只有一条规矩:从右往左,范围由大到小。

第一张图上排是日常地址、下排是域名——两行读的是同一件事:先圈定大范围,最后落到具体那一台。区别只在方向:地址从左往右,域名从右往左。

❗ 为什么偏偏要"倒着写"

因为处理域名的每一台服务器,都只关心自己那一段。

根服务器只认最右边那一级的后缀(.com 还是 .cn),顶级域服务器只认后缀前面那一段(baidu),权威服务器才认最左边的主机名。从右往左一层层往里剥,正好就是查询的推进顺序——域名的写法是为查询流程量身定做的。

换句话说:域名的书写顺序 = DNS 服务器的层级顺序。 这一条把这节的图一和图二串成了一根线。

再补两条工程上很实用的推论:

四、DNS 是什么:一整套分布式电话簿

DNS = Domain Name System(域名系统)。它的全名里有个关键字——System(系统),不是 Server(服务器)。

❗ 核心认知 ①:DNS 不是一台服务器,是一套分层系统

全世界没有任何一台机器存着所有域名。 它从上到下分成三层,各管一段:

层 管什么 有多少
根域名服务器 只知道".com 归谁管、.cn 归谁管" 13 组 IP(全球上百个镜像分摊)
顶级域服务器 管 .com 底下有哪些域名,各归谁管 每个后缀一组(.com 一组、.cn 一组……)
权威域名服务器 管某个域名的真实记录(baidu.com 的 IP 到底是什么) 每个域名一套,由域名所有者/服务商配置

从上往下:范围一层比一层小,信息一层比一层具体——和域名的四层结构一一对应。

为什么不做成一本大表? 三个理由,都是硬伤:

  1. 量太大——全球域名数以亿计,还要频繁变动,没有任何一台机器扛得住
  2. 单点故障——就一台,坏了全世界断网
  3. 更新传不动——每天新增/修改的域名要实时同步到全世界,根本来不及

分成三层之后,每台服务器只维护自己那一小段,既分摊了压力,又天然没有单点。这正是 3.9 那套"分段隔离"和 1.4 那套"网络的网络"的思想,又一次在应用层重现。

本地 DNS 服务器:替你跑腿的那个人

上面三层是"被问的人"。那谁去问?——本地 DNS 服务器(又叫递归解析器),由运营商或路由器提供(收 3.12 四件套的第四件)。

两种问法的区别,是本节最值得记住的一组术语:

递归查询 迭代查询
谁在问 你的电脑 → 本地 DNS 本地 DNS → 根 / 顶级域 / 权威
问法 "帮我查出来就行"(你只问一次) "这个我不管,你去找他"(被问的人只给线索)
结果 本地 DNS 必须给你最终答案 每次只回一句"往下找谁"

你的电脑只发一次递归查询,剩下的都是本地 DNS 替你跑腿。 这就是为什么你在浏览器里敲个域名,感觉自己只"发出了一句话",而实际网络上跑了好几趟——那几趟你看不见。

五、一次完整查询是怎么走完的(本节第二张图)

第二张图画的就是上面这条链。把图上的 ①②③ 展开成完整步骤:

步 谁问谁 问什么 答什么
0 本机先自理 查本机缓存 → 查 hosts 文件 → 查本地 DNS 缓存 命中就直接用,后面的步骤全省
1 你的电脑 → 本地 DNS 递归查询:www.baidu.com 的 IP? —
② 本地 DNS → 根域名服务器 .com 谁管? 去问 .com 那组服务器(给的是线索)
③ 本地 DNS → 顶级域服务器 baidu.com 谁管? 去问 baidu 的权威服务器(还是线索)
④ 本地 DNS → 权威域名服务器 www.baidu.com 的 IP? 110.242.68.66(终于是真话了)
5 本地 DNS → 你的电脑 把 IP 给你,同时自己缓存一份 你也可以缓存一份

三个必须记住的细节:

① 只有最后一步拿到的是"真话",前面全是"线索"。 根和顶级域服务器都不存具体 IP——它们只负责指路。这是分布式设计的核心:中间层越"无知",可维护性越高。

② 你的电脑只跟本地 DNS 说了一次话,那 ②③④ 三趟都是本地 DNS 自己跑的(图上是"同一个框向右发了三支箭")。

③ 答案会被一路缓存。 你的电脑会存,本地 DNS 也会存,TTL(生存时间)决定存多久。这就是为什么第二次访问同一个网站快得多——本地 DNS 那一步就命中缓存了,压根没往上游走。

💡 顺手收 3.17 / 3.20 的两笔账

DNS 查询默认走 UDP 53: - 3.17 那张已知端口名册里的 53 DNS,本节解释了为什么它是"查询走 UDP、大响应走 TCP" - 3.20 说的"DNS 是 UDP 最典型的应用",原因就在这一步:一问一答、极其短小,为它做三次握手是纯浪费——如果每次查域名都要先握手再挥手,上网体验会明显变慢

什么时候转 TCP?两种情况下 UDP 装不下: - 响应超过 512 字节(比如一个大域名带一堆 IP,或开了 DNSSEC) - 区域传送(主从 DNS 服务器之间同步整份数据,量大且要求可靠)

⚠️ 一个反常识的点:ping 域名会先"解析"

ping www.baidu.com 其实发生了两件事,按顺序: 1. 先把域名解析成 IP(这一步出错 → 报「找不到主机」) 2. 再拿 IP 去 ping(这一步出错 → 报「请求超时」或「无法访问目标主机」)

3.12 那套三层排障法的第三条能定位 DNS 问题,靠的就是这个顺序。而 3.15 特别强调过:「找不到主机」这条报错不是 ICMP 发的,是 DNS 层面的错——两节在这里对上了。

六、DNS 里存了些什么:常见的记录类型

电话簿里不是只有"人名 → 号码",还有"单位 → 总机""某人的别名"等等。DNS 也一样,一张表里可以放好几种资源记录(Resource Record,RR):

类型 存什么 例子 用途
A 域名 → IPv4 地址 www.baidu.com → 110.242.68.66 最常用的一种
AAAA 域名 → IPv6 地址 www.baidu.com → 240e:... IPv4 的近亲
CNAME 域名 → 另一个域名(别名) www.baidu.com → baidu.com 换服务器时只改一处,别名跟着变
MX 这个域的邮件服务器是谁 baidu.com → mx.baidu.com 收 1.5 的应用层名单:邮件用的
NS 这个域归哪台服务器管 baidu.com → ns1.baidu.com 就是"权威服务器"在表里的写法
PTR IP → 域名(反向) 110.242.68.66 → www.baidu.com 反向解析,见下
TXT 一段文字 验证信息、发信策略 域名归属验证(很多平台要你加一条)

两个值得单独说的:

七、本机的小电话簿:hosts 文件与缓存

DNS 是一整套全球系统,但你的电脑自己也有两本小抄,而且它们排在 DNS 前面:

1. hosts 文件——优先级最高的"手写小电话簿"

路径(Windows):

C:\Windows\System32\drivers\etc\hosts

它是一个纯文本文件,一行一条,格式是 IP 域名:

127.0.0.1    www.test123.com

优先级最高——本机查域名时,先看它,再问 DNS。命中就直接用,DNS 那一整套流程一步都不走。

它在今天仍在被大量使用,三个典型用途:

用途 怎么用
本地开发测试 把 myproject.local 指到 127.0.0.1,不用真的买域名
屏蔽广告/恶意网站 把广告域名指向 0.0.0.0(一个不存在的地址),请求直接掉进黑洞
临时改解析做验证 服务器要换 IP 了,先在本机 hosts 里试一遍,确认没问题再改正式解析
💡 这也解释了为什么它是"老古董却杀不死"

hosts 的历史比 DNS 还早(早期互联网就那么几台机器,一份名单文件就够了)。DNS 出现后它本该退休,但"本机说了算"这个能力一直有用——于是留到了今天。

反过来说,它也是一个安全隐患点:恶意软件改你的 hosts,就能把你导向假的银行网站。所以查"域名解析异常"时,看一下 hosts 文件是标准动作。

2. 缓存——真正让你感觉"快"的那个

缓存一共三级:本机 DNS 缓存 → hosts → 本地 DNS 服务器缓存(后面还有上游各级)。

它带来两个直接后果:

这解释了一个很常见的困惑:"我明明改了解析,为什么还是访问到旧服务器?"——不是没改成功,是缓存还没过期。TTL 短(比如 60 秒)生效快但查询压力大,TTL 长(比如 24 小时)省事但改起来磨人,这是运维上的一个经典取舍。

八、动手 Demo35:把电话簿翻出来看

  1. 亲手查一次(本节最直接的一步) nslookup www.baidu.com 看两部分:"服务器"那一行(= 你正在问的本地 DNS 是谁,一般就是你家路由器或运营商)、下面那几行 Address(= 解析出来的 IP,常常不止一个)。

  2. 换个电话簿问问,对比一下 nslookup www.baidu.com 8.8.8.8 强行指定用 Google 的公共 DNS(8.8.8.8)去查。同一域名,不同 DNS 给出的 IP 常常不一样——因为大网站有多个 IP,各家 DNS 返回哪几个是它自己决定的(也顺手证明:域名解析结果不是唯一的)。

  3. 看本机缓存里存了些什么(信息量很大) ipconfig /displaydns 会列出你最近访问过的域名和它们的记录——这就是那本"自动生成的小电话簿"。往下翻,能看到各种 A 记录和 CNAME。注意看每条都有 TTL 那一栏,可以亲眼看到剩余时间。

  4. 清空它(排障常用) ipconfig /flushdns 清完再 ping 一下刚才的域名,会发现第一次稍慢一点——因为缓存空了,得重新去问一遍。这组对照很直观。

  5. 看"这个域归谁管" nslookup -type=ns baidu.com 或者用交互模式一次看几种记录: ``` nslookup

    set type=ns baidu.com set type=mx baidu.com `` 你会看到.com` 那一层返回的正是"权威服务器"的名字——这就是第二张图里顶级域服务器那一步的实物。

  6. hosts 文件实验(做之前先备份)

    改系统文件,先备份 1. 先把 hosts 复制一份(比如 hosts.bak)——这一步不能省 2. 用管理员权限打开记事本,在末尾加一行:127.0.0.1 www.test123.com 3. ping www.test123.com——会解析到 127.0.0.1(你自己),说明 hosts 优先级高于 DNS 4. 再 nslookup www.test123.com——会发现 nslookup 查不到它,因为 nslookup 是直接问 DNS 的,不看 hosts 5. 把那一行删掉,恢复原样(或直接用备份覆盖回去)

    第 4 步那个"对不上"很有价值:它证明 hosts 和 DNS 是两套独立的来源,而系统解析域名的顺序是"先 hosts、后 DNS"。有些"明明改了却没生效"的怪事,根子就在这里。

  7. 回到 Java 看一眼(收 13.1 的账) 把 13.1 的 Demo22 跑一遍:InetAddress.getByName("www.baidu.com") 打印出 IP——这一行代码,就是本节整套流程在程序里的入口。再把域名改成乱写的(www.abc123xyz999.com),看它抛 UnknownHostException——"查无此人",和 ping 域名报「找不到主机」是同一件事。

  8. 30 秒实验:分辨两种"不通" ping www.baidu.com ← 正常,先解析再 ping ping www.zzzz-not-exist.com ← 观察报的是哪一句 第二条报的应该是「找不到主机」——这条不是 ICMP 发的,是 DNS 层面的错(收 3.15)。能分清这一点,3.12 那套排障法才算真正用活。

❓ 自测一下
  1. 既然机器只认 IP,为什么还要域名?不能人人记 IP 吗?
  2. 主机名和域名有什么区别?各自的作用范围是什么?
  3. 域名为什么要从右往左读?这个方向是哪来的?
  4. DNS 为什么不做成一本大表,非要分成三层?
  5. 递归查询和迭代查询,区别在哪?
  6. 一次 DNS 查询里,本地 DNS 服务器一共替你去问了几趟?为什么要问好几趟?
  7. DNS 查询为什么默认走 UDP?什么时候会换成 TCP?
  8. 改了域名解析,为什么访问到的还是旧服务器?
  9. nslookup www.test123.com 查不到,但 ping 能通——可能是什么原因?

答案: ① 因为人记不住、IP 会变。域名把"会变的地址"藏在"不变的名字"后面,同时把数字换成好念的字符串(并额外提供 .com/.cn 这类分类信息)。 ② 主机名是一台设备自己的名字(常常只在本机或本网段有效,不保证全球唯一);域名是在互联网上通行、由 DNS 全球解析的名字(同一时刻唯一)。 ③ 因为每一级 DNS 服务器只关心自己那一段:根只认后缀、顶级域认后缀前一段、权威才认主机名。从右往左一层层往里剥,正好就是查询的推进顺序——域名的书写顺序 = DNS 服务器的层级顺序。 ④ 量大且变动频繁(一台机器存不下、跟不上)、单点故障(一台挂了全球断网)、更新传不动(无法实时同步到全世界)。分层后各管一段,压力分摊且天然无单点。 ⑤ 递归查询是"你问本地 DNS、它必须给你最终答案"(你只问一次);迭代查询是"本地 DNS 去问根/顶级域/权威,被问的只回一句线索(去找谁)",得自己接着跑。 ⑥ 三趟(根 → 顶级域 → 权威)。因为没有任何一台服务器存着全部域名,根和顶级域只知道一部分线索,只有权威服务器才握着真实 IP。 ⑦ 因为 DNS 是一问一答、极短小的典型场景,为它做三次握手纯属浪费(收 3.20)。响应超过 512 字节(大响应、DNSSEC)或区域传送(主从同步整份数据)时换成 TCP 53。 ⑧ 因为缓存还没过期。你改了权威服务器上的记录,但各级缓存(本机、本地 DNS、上游)都要等 TTL 到期才会重新去取。 ⑨ 很可能是 hosts 文件里写了这一条——nslookup 是直接问 DNS 的、不看 hosts,而系统解析域名是先 hosts、后 DNS。两者来源不同,所以结果对不上。

九、几条实战规矩

1. 排障时"解析"和"连通"要分开测

遇到"网站打不开",先分清是哪一段:

现象 定位 怎么办
ping 域名 报「找不到主机」 解析环节 查 DNS 服务器地址、查 hosts、nslookup 换一个 DNS 对比
ping 域名 能解析出 IP,但「请求超时」 连通环节 就不是 DNS 的事了,按 3.12 那套往下查(收 3.15)
nslookup 结果对但浏览器还是不行 可能是本机缓存或 hosts ipconfig /flushdns,再查 hosts

"能不能解析出 IP"这一条,就能把问题砍成两半——这是本节最实用的排障价值。

2. 别乱改 DNS 服务器地址

有些人为了"加速"把 DNS 换成公共 DNS(8.8.8.8、114.114.114.114 等)。要注意两点:

3. hosts 是"临时手术刀",不是长期方案

本地调试很方便,但它只对你这台机器有效,而且容易被忘记(几个月后自己都莫名其妙)。改完记得清理,改前记得备份。

4. 域名是"租"的,不是"买断"的

注册域名是按年付费的使用权,到期不续费会被释放、别人可以注册。这也是很多公司一次续十年的原因——域名丢了,品牌和所有外部链接一起丢。

十、常见误区

  1. ❌ "域名就是 IP 换了个写法" → 域名是名字不是地址,靠 DNS 翻译;而且不是一对一(一个域名可对应多个 IP,一个 IP 也可对应多个域名)
  2. ❌ "网址(URL)就是域名" → URL 里还有协议、路径、参数,域名只是其中一段
  3. ❌ "全世界有一台 DNS 服务器在管所有域名" → 是分层分布式系统:根(13 组 IP、上百镜像)→ 顶级域 → 权威,各管一段
  4. ❌ "域名从左往右读" → 从右往左,范围由大到小;这个方向来自 DNS 服务器的层级顺序
  5. ❌ "DNS 只能用 UDP" → 查询默认 UDP 53;响应超 512 字节或区域传送走 TCP 53(收 3.17)
  6. ❌ "改了域名解析马上全世界生效" → 各级缓存 + TTL,得等过期(这是"改了没生效"的头号原因)
  7. ❌ "DNS 出问题 = 网断了" → 收 3.12:能 ping 通 IP、ping 域名不通,说明网络本身没坏,坏的只是"查号"这一件
  8. ❌ "ping 域名不通就是网站挂了" → 报「找不到主机」是解析失败;而且有些服务器故意禁 ICMP(收 3.15),ping 不通不代表服务不可用
  9. ❌ "hosts 是被淘汰的老古董" → 它优先级最高、仍在大量使用(本地开发、屏蔽广告、临时改解析)
  10. ❌ "域名买了就永久属于我" → 是按年租用,不续费会被释放

十一、下一步学什么

相关笔记