from - zero

00. 从 0 开始理解计算机网络

0. 本章先解决什么问题

计算机网络解决的是:

一台机器上的进程
如何和另一台机器上的进程交换数据?

你在应用里看到的可能只是:

访问一个 URL
下载一个文件
发一条消息
调用一个远程接口

但底层要经过:

  • 域名解析。
  • 建立传输连接或选择无连接发送。
  • 加密握手。
  • 应用协议封装。
  • 操作系统 Socket。
  • IP 寻址和路由。
  • 局域网帧传输。
  • 网卡、中断、缓冲区。
  • 对端反向解封装。

本章先建立全局地图,后面再逐层拆。

网络分层路径

这张图怎么读

这张图是本模块的主图。以后看到任何网络现象,都先把它放回某一层:

现象不要急着说先放回哪层
域名解析不到网络全坏了DNS / 命名系统
端口连不上服务一定挂了TCP/UDP + 防火墙 + 监听状态
证书报错应用逻辑错了TLS 身份认证
502/504代码一定异常代理、网关、上游路径
下载慢带宽一定不够RTT、丢包、窗口、接收速度

1. 网络的最小模型

最小网络通信模型:

进程 A
-> 本机操作系统
-> 本机网卡
-> 中间网络设备
-> 对端网卡
-> 对端操作系统
-> 进程 B

通信本质是:

把数据从一个进程的地址空间
搬到另一个进程的地址空间

中间不能只靠一根“线”。必须解决:

  • 对方是谁?
  • 数据往哪里发?
  • 中间设备怎么转发?
  • 数据丢了怎么办?
  • 顺序乱了怎么办?
  • 数据是否被篡改?
  • 对方身份是否可信?
  • 发送太快怎么办?
  • 网络拥塞怎么办?

2. 为什么要分层

网络太复杂,不分层就很难维护。

分层的思想:

每一层只解决一组问题
向上提供服务
向下依赖下一层能力

简化层次:

解决什么
应用层应用语义:请求、响应、域名、网页、文件
传输层进程到进程:端口、可靠性、流量控制
网络层主机到主机:IP、路由、跨网络转发
链路层相邻设备传输:MAC、帧、局域网
物理层bit 如何在介质上传输

每层都有自己的地址、数据单位、错误和边界。

3. 一次访问大致经过什么

访问:

https://example.com/index.html

可能经历:

解析域名
-> 得到目标 IP
建立 TCP 或 QUIC 连接
-> 和目标主机建立传输通道
TLS 握手
-> 认证身份,协商密钥
发送 HTTP 请求
-> 请求某个资源
服务器处理
-> 返回 HTTP 响应
本机接收数据
-> 解密、解析、交给应用

中间任何一步都可能失败。

4. 地址体系:不同层有不同地址

网络里有多种地址。

地址层次作用
域名应用层人类友好的名字
IP 地址网络层标识网络中的主机或接口
端口传输层标识主机上的进程入口
MAC 地址链路层局域网内相邻设备传输

例子:

www.example.com -> 93.184.216.34
目标端口 -> 443
下一跳 MAC -> 局域网里实际发送帧的目标

不要把域名、IP、端口、MAC 混成一类。

5. 数据单位:每层都有自己的包

数据单位
应用层message、request、response
传输层segment 或 datagram
网络层packet
链路层frame
物理层bit

发送时封装:

应用数据

  • 传输层头
  • IP 头
  • 链路层头尾
    -> bit 流

接收时解封装:

bit
-> frame
-> packet
-> segment/datagram
-> 应用数据

6. 网络不保证一切

网络天然不可靠。

可能发生:

  • 丢包。
  • 重复包。
  • 乱序。
  • 延迟抖动。
  • 带宽不足。
  • 中间设备故障。
  • 路由变化。
  • MTU 限制。
  • 对端关闭。
  • NAT 状态过期。
  • DNS 缓存错误。

不同协议在不同层补救一部分问题。

例如 TCP 解决可靠有序字节流,但它不解决:

  • 应用消息边界。
  • 对端业务是否处理成功。
  • 数据是否应该被信任。
  • 网络拥塞之外的应用排队。

反例:每一层都“成功”,端到端仍可能失败

网络学习里最危险的误判之一,是把某一层成功当作整条链路成功。

看一个请求:

DNS 成功解析
TCP 成功连接
TLS 成功握手
HTTP 请求成功发出
入口代理返回 200
客户端收到响应

这看起来已经全部成功,但端到端语义仍可能失败:

已成功的层仍可能失败的事
DNS解析到了旧地址或错误区域
TCP对端进程接了连接,但业务线程池已满
TLS身份和加密成立,但应用权限失败
HTTP状态码 200,但响应体是错误页或旧缓存
代理代理返回成功,但上游执行的是降级逻辑
客户端接收客户端解析、校验、保存结果失败

所以端到端排障要最后回到业务语义:

数据是否被正确的对端处理?
处理结果是否符合协议和业务约定?
响应是否来自预期的层和版本?

分层给你定位工具,但最终成功条件由端到端语义定义。

7. 延迟和带宽

网络性能至少看两个维度:

指标含义
延迟一次数据往返或到达需要多久
带宽单位时间最多能传多少数据

低延迟不等于高带宽。

高带宽不等于单次请求快。

影响延迟:

  • 物理距离。
  • 排队。
  • DNS。
  • 握手次数。
  • TLS。
  • 服务器处理。
  • 丢包重传。

影响吞吐:

  • 链路带宽。
  • TCP 窗口。
  • 拥塞控制。
  • 接收方处理速度。
  • 应用读写速度。

8. OS 在网络里的位置

应用通常通过 Socket 使用网络。

路径:

应用 buffer
-> 系统调用 send/recv
-> 内核 socket buffer
-> TCP/UDP/IP 协议栈
-> 网卡驱动
-> 网卡

所以网络问题可能在:

  • 应用没有及时读写。
  • 内核缓冲区满。
  • event loop 被阻塞。
  • 线程池耗尽。
  • TCP 状态异常。
  • DNS 失败。
  • 路由失败。
  • 对端慢。

网络不是只属于网络课,它和 OS 强连接。

9. 联系实际:一个请求慢怎么先拆

请求慢时,不要直接说“网络慢”。

按路径拆:

  1. 域名解析慢吗?
  2. TCP/QUIC 连接建立慢吗?
  3. TLS 握手慢吗?
  4. 请求是否成功发出?
  5. 服务端是否收到?
  6. 服务端处理慢吗?
  7. 响应是否已经返回?
  8. 客户端是否及时读取?
  9. 是否丢包、重传、拥塞?
  10. 是否代理、网关、负载均衡排队?

这就是网络排障的基本证据链。

这也可以变成一张排障卡:

阶段你要看的证据常见误判
DNS解析耗时、解析结果、TTL把解析失败当成 TCP 失败
TCPconnect 耗时、SYN/ACK、RST把端口拒绝当成应用 500
TLS证书链、SNI、协议版本把握手失败当成 HTTP 错
HTTP状态码、Header、首字节时间只看状态码,不看是谁返回的
下载响应体大小、吞吐、重传把大文件下载慢当成服务处理慢

一个适合自己练的小实验:访问同一个站点,分别记录 DNS、TCP、TLS、首字节、下载阶段耗时。你会发现“请求慢”很少是单一原因,慢点落在哪一段,解决方向完全不同。

手推:一次请求的延迟最少由哪些等待组成

把一次远程请求粗略拆开:

总耗时 =
DNS 查询

  • 连接建立
  • TLS/安全握手
  • 请求上传
  • 对端排队
  • 对端处理
  • 首字节返回
  • 响应体下载

如果一次请求总共 1200ms,不要直接说“网络慢”。可能是:

阶段耗时
DNS5ms
连接30ms
TLS60ms
请求上传5ms
对端排队900ms
对端处理80ms
首字节返回20ms
下载100ms

这种情况下主要慢点不是网络传输,而是对端排队。换一种情况:

阶段耗时
DNS700ms
连接30ms
TLS60ms
处理80ms
下载100ms

主因就变成解析阶段。网络学习必须从“总耗时”拆到“阶段耗时”,因为不同阶段对应完全不同的机制和修复方向。

边界条件:丢包不是只有“完全断网”才会发生

网络失败不是二值的。很多时候不是完全不通,而是:

代码块JAVA · 2 行收起展开
大多数包能到;
少量包丢失、乱序或延迟很高;

协议通过重传和等待勉强恢复。

这会造成反直觉现象:

现象可能解释
小请求正常,大响应慢响应包多,更容易遇到丢包/重传
平均延迟还行,P99 很差偶发重传或队列排队拉长尾部
ping 偶尔丢 1%应用层可能出现明显尾延迟
带宽没满但下载慢拥塞控制、窗口、丢包限制吞吐

所以网络排障不能只问“通不通”,还要问:

丢包率是多少?
重传是否增加?
延迟分布是否有长尾?
大包和小包是否表现不同?

排障卡:把“网络慢”拆成四段

当你听到一句“网络慢”,先不要急着猜协议。把一次访问拆成四段,每段只问一个可验证的问题:

阶段核心问题常见证据更可能的方向
找到对方名字能不能变成地址?DNS 查询时间、解析结果是否变化域名、缓存、解析链路
到达对方包能不能走到目标网络?ping / traceroute / 路由表 / 丢包率路由、网关、防火墙、链路
建立会话连接能不能完成?SYN 重传、握手耗时、连接错误TCP 状态、端口、服务监听
传输数据数据是否被及时处理?首字节时间、吞吐、重传、应用日志拥塞、窗口、队列、服务处理

一个可操作的练习:找一个你常访问的网站,记录解析耗时、连接耗时、首字节时间和下载时间。然后思考:如果总耗时突然增加 2 秒,这 2 秒分别可能落在哪个阶段?你不需要立刻会所有工具,只要先学会把“慢”拆成可定位的问题。

10. 学完本章你能解决什么问题

学完这一章,你应该能解决或开始分析这些问题:

  1. 网络通信的目标为什么是进程到进程?
  2. 域名、IP、端口、MAC 分别属于哪一层?
  3. 为什么网络要分层?
  4. 封装和解封装是什么?
  5. 一次 HTTPS 请求大致经过哪些阶段?
  6. 网络为什么天然会丢包、乱序、延迟抖动?
  7. 延迟和带宽有什么区别?
  8. 请求慢时如何按 DNS、连接、TLS、应用、网络路径拆分?

计算机网络的核心不是“会背协议名”,而是能画出数据从一个进程到另一个进程的路径。

延伸阅读