上网这件事被拆成四层来干,每层只管自己那一小段;层层套壳之后,一段文字才变成能穿越大半个地球的包裹。
3-1 列了一张支撑技术的全景表,这一节从表里最底下的那一层讲起:TCP/IP 是一整套协议族,不是单个协议。它是后面 DNS、DHCP、TLS 全部站上去的地基。
一、为什么要分层
如果全世界的网络只用一套规则,那么任何一处改动都要全世界跟着改——换个网卡技术、换个传输方式,都得重新设计一遍。
分层的思路是把问题切开:每一层只管自己的那一小段,层与层之间只约好接口。这样换掉某一层的东西,其他层不用动。这也是网络能从几十台机器长到今天这个规模的原因。
二、四层各自的本职
TCP/IP 通常分四层,从下往上分别是链路层、网络层、传输层、应用层。
链路层管【这一跳】:在相邻的两台设备之间把数据送过去,典型协议是以太网和 Wi-Fi。
网络层管【从起点到终点】:给每台机器编号并按编号找路,主角是 IP。它只负责尽力送达,不保证顺序、也不保证不丢。
传输层管【完整有序】:TCP 把大块数据切成段、编上号,丢了就重发;UDP 则相反,图快不图全。
应用层管【给用户提供什么服务】:HTTP 取网页、DNS 查名字、FTP 传文件、SMTP 发邮件,全在这一层。
三、动手 Demo:套壳的账与等待的账
数据不是凭空过去的,它每往下走一层就要加一段头。这段头不多,但架不住层层都加。
head = {"HTTP 头": 400, "TCP 头": 20, "IP 头": 20, "以太网头": 14, "帧校验": 4}
body = 1000
total = body + sum(head.values())
print("净荷", body, "字节,实际发出", total, "字节")
print("开销 %d 字节,占 %.1f%%" % (sum(head.values()), sum(head.values()) * 100.0 / total))
print("净荷占比 %.1f%%" % (body * 100.0 / total))
实跑输出:
--------------------------------------------------------------------
D2 TCP/IP:四层怎么分工、每层加多少头
--------------------------------------------------------------------
TCP/IP 不是单个协议,而是一整套。它把活分成四层,每层只管自己那一摊,
上一层的数据往下走的时候,每一层都要给它套一层壳。
层 本职 典型协议
--------------------------------------------------------------------------------------
应用层 决定给用户提供什么服务 HTTP、DNS、FTP、SMTP
传输层 把数据切成段、保证完整有序 TCP、UDP、QUIC
网络层 给每台机器编号并按编号找路 IP、ICMP、ARP
链路层 在相邻两台设备之间传这一跳 以太网、Wi-Fi
发一条 1000 字节的正文,一路上要套几层壳:
层次 加了什么 字节 累计
----------------------------------------------------------------------------
正文 要传的内容本身 1000 1000
应用层 HTTP 头(含 Cookie 等) 400 1400
传输层 TCP 头(端口、序号) 20 1420
网络层 IP 头(源与目的地址) 20 1440
链路层 以太网头(MAC 地址) 14 1454
链路层 帧校验(FCS) 4 1458
净荷 1000 字节,实际发出去 1458 字节
多出来的壳 458 字节,占 31.4%
真正有用的部分只占 68.6%
壳看着多余,但正是它让【一段文字】变成了【能穿越大半个地球的包裹】。
再说【等多久】。TCP 要先把连接建立起来才能传数据,这一来一回的耗时叫 RTT:
场景 一次往返 建连接要多久
------------------------------------------------------------------
同一个局域网 1 ms 1 ms
同一个城市 10 ms 10 ms
跨省 30 ms 30 ms
跨太平洋 150 ms 150 ms
注意:这只是建立连接。如果还要走 HTTPS,加密握手起码再来一次往返。
两笔账值得记住。第一笔是套壳的账:1000 字节的正文,发出去变成 1458 字节,多出来的 458 字节全是头,占了三成。头看着浪费,但它正是【一段文字】能变成【能穿越大半个地球的包裹】的原因。
第二笔是等待的账:TCP 要先把连接建立起来才能传数据,这一来一回的耗时叫 RTT。同一个局域网 1 毫秒无所谓,跨太平洋 150 毫秒就肉疼了——因为后面还要握手,而握手是按【往返次数】算的。
四、用一层的眼光想问题
分层不只是画图好看,它直接决定了排查和优化的方向。
网站打不开,先按层往下问:域名能不能解析(应用层)、端口通不通(传输层)、能不能 ping 到(网络层)、网线灯亮不亮(链路层)。一层一层测下来,故障点很快就锁定了。
优化也一样:想减少等待,压缩的是往返次数;想减少体积,动的是头的数量。知道自己在哪一层动刀,才不会做无用功。
30 秒实验
- 在命令行运行
ping 8.8.8.8,看输出里的time=xx ms——那就是一次往返的耗时,也是握手耗时的基本单位。 - 运行
tracert www.baidu.com(Windows)或traceroute(macOS / Linux),数一数从你家到服务器一共经过路由器几跳。 - 在开发者工具的 Network 面板里看 Connection 那一列写的是
h2还是h3,这能看出你走的是 TCP 还是 QUIC。
常见误区
- 错误:TCP/IP 是一个协议。——纠正:它是一整套协议族,TCP 和 IP 只是其中最有名的两个。同一个筐里还装着 UDP、ICMP、ARP、HTTP、DNS 等等。把它当成【一整套规则】,才不会到处找不到【那个叫 TCP/IP 的协议】。
- 错误:分层只是为了分类好看。——纠正:分层的真正价值是可替换。在 IP 之上既可以用 TCP,也可以用 UDP 和 QUIC——HTTP/3 就是靠这一点才换得动传输层。
- 错误:每层加的那些头是浪费。——纠正:每段头都在解决一类问题:端口决定交给哪个程序、IP 决定送到哪台机器、MAC 决定交给哪块网卡。去掉任何一段,对应那件事就没人干了。
- 错误:TCP 一定比 UDP 好。——纠正:它们服务的目标不一样。TCP 要的是【一个字节都不少】,UDP 要的是【别等】。直播、语音这种【迟到的数据没用】的场景,反而应该选 UDP。
自测三问(点开对答案)
1. 四层各自解决什么问题? —— 链路层解决【这一跳怎么送】,网络层解决【从起点到终点怎么找路】,传输层解决【数据完整有序】,应用层解决【给用户什么服务】。**记的时候按【一跳、一路、一段、一层服务】来记**,比背协议名管用。 2. 1000 字节的正文为什么会变成 1458 字节? —— 因为每往下走一层就要加一段头:HTTP 头 400 字节、TCP 头 20 字节、IP 头 20 字节、以太网头 14 字节、帧校验 4 字节,**加起来 458 字节**。**这个比例说明:小文件传输的开销占比会特别难看**——所以小图片要合并、要内联。 3. 为什么跨洋访问对握手次数特别敏感? —— 因为**握手是按往返次数算的**,一次往返 150 毫秒。TLS 1.2 要 2 次、TLS 1.3 只要 1 次,**差的就是实打实的 150 毫秒**。距离没法缩短,能缩的只有往返次数。- ☐ 下一节(3-3 IP地址与MAC地址的区别:IP 地址、MAC 地址)
相关笔记
- 为整个Web提供支持的技术 —— 上一节:本章的全景图
- 负责传输数据的网络分层 —— 网络课里对同一套分层的展开
- 对应用程序的数据进行可靠传输(TCP) —— TCP 的机制细节
- Web网站的HTTP请求 —— 应用层里最常用的那个协议
- 🕸️ Web技术原理 · 索引