计算机网络手册
速查向 · TCP/IP 分层、TCP 可靠传输与握手挥手、HTTP 演进、HTTPS 与 TLS、DNS、常见问题解析
1. 分层模型与基础
1.1 OSI 七层 vs TCP/IP 四层
| OSI 七层 | TCP/IP 四层 | 协议举例 |
|---|---|---|
| 应用层 / 表示层 / 会话层 | 应用层 | HTTP、HTTPS、DNS、FTP、SMTP、SSH |
| 传输层 | 传输层 | TCP、UDP |
| 网络层 | 网络层 | IP、ICMP、ARP、OSPF |
| 数据链路层 / 物理层 | 网络接口层 | 以太网、Wi-Fi、PPP |
数据封装:应用数据 → 加 TCP 头(段 Segment)→ 加 IP 头(包 Packet)→ 加帧头帧尾(帧 Frame)→ 比特流。
1.2 输入 URL 到页面展示(经典)
- DNS 解析:域名 → IP(浏览器缓存 → 系统缓存 → hosts → 本地 DNS → 根/顶级/权威)。
- 建立 TCP 连接:三次握手。
- TLS 握手(HTTPS):协商密钥、验证证书。
- 发送 HTTP 请求,服务器处理并返回响应。
- 浏览器渲染:解析 HTML → 构建 DOM → CSSOM → 渲染树 → 布局 → 绘制。
- 断开连接:四次挥手(HTTP/1.1 默认 keep-alive 会复用连接)。
1.3 地址与端口
- IP:网络层寻址;端口:传输层标识进程(0-65535,0-1023 系统保留)。
- MAC:链路层寻址,局域网内使用。
- ARP:由 IP 找 MAC(同网段广播,跨网段先发给网关)。
- ICMP:ping / traceroute 使用,网络层协议。
2. TCP 核心机制
2.1 TCP vs UDP
| 维度 | TCP | UDP |
|---|---|---|
| 连接 | 面向连接(需握手) | 无连接 |
| 可靠性 | 可靠(确认、重传、排序) | 不可靠,尽最大努力 |
| 传输方式 | 字节流 | 数据报(保留边界) |
| 首部开销 | 20-60 字节 | 8 字节 |
| 速度 | 慢(有拥塞控制) | 快(无拥塞控制) |
| 一对多 | 只支持一对一 | 支持广播/组播 |
| 场景 | 文件传输、HTTP、数据库 | 视频直播、DNS、游戏、VoIP |
QUIC/HTTP3 为什么用 UDP?——在用户态实现可靠传输与拥塞控制,避免 TCP 队头阻塞,且握手更快(0-RTT)。
2.2 三次握手
- SYN:客户端 → 服务端,
SYN=1, seq=x,进入 SYN_SENT。 - SYN+ACK:服务端 → 客户端,
SYN=1, ACK=1, seq=y, ack=x+1,进入 SYN_RCVD。 - ACK:客户端 → 服务端,
ACK=1, seq=x+1, ack=y+1,双方 ESTABLISHED。
Q:为什么是三次而不是两次?
防止已失效的历史连接请求突然到达服务端,导致服务端建立无用连接、浪费资源。
本质是双方都要确认对方的收发能力,两次无法确认客户端的接收能力。
本质是双方都要确认对方的收发能力,两次无法确认客户端的接收能力。
Q:第三次握手可以携带数据吗?
可以。第三次握手时客户端已确认服务端收发正常,可以携带数据。
2.3 四次挥手
- FIN:主动方 → 被动方,
FIN=1, seq=u,主动方进入 FIN_WAIT_1。 - ACK:被动方 → 主动方,
ACK=1, ack=u+1,被动方进入 CLOSE_WAIT,主动方进入 FIN_WAIT_2。 - FIN:被动方处理完数据后 → 主动方,
FIN=1, seq=w,被动方进入 LAST_ACK。 - ACK:主动方 → 被动方,
ACK=1, ack=w+1,主动方进入 TIME_WAIT,等待 2MSL 后关闭。
Q:为什么挥手是四次,握手是三次?
TCP 是全双工的。握手时服务端可以把 SYN(我要连)和 ACK(我听到了)合并在一个包里;
而挥手时,被动方收到 FIN 后可能还有数据没发完,只能先回 ACK,等数据发完再单独发 FIN,无法合并。
而挥手时,被动方收到 FIN 后可能还有数据没发完,只能先回 ACK,等数据发完再单独发 FIN,无法合并。
Q:TIME_WAIT 为什么等 2MSL?
① 保证最后一个 ACK 能到达对方(丢了对方会重发 FIN,此时还能响应);
② 让本次连接的所有报文在网络中消失,避免影响下一个使用相同四元组的新连接。
MSL 是报文最大生存时间,Linux 默认 2MSL = 60 秒。
② 让本次连接的所有报文在网络中消失,避免影响下一个使用相同四元组的新连接。
MSL 是报文最大生存时间,Linux 默认 2MSL = 60 秒。
Q:大量 TIME_WAIT / CLOSE_WAIT 怎么办?
TIME_WAIT 过多(主动关闭方):很正常,通常不用怕。可开启
CLOSE_WAIT 过多(被动关闭方):这是 bug——说明应用收到 FIN 后没调用 close(),通常是代码没关连接或处理太慢,要查应用代码。
tcp_tw_reuse 复用、增大端口范围、用连接池。CLOSE_WAIT 过多(被动关闭方):这是 bug——说明应用收到 FIN 后没调用 close(),通常是代码没关连接或处理太慢,要查应用代码。
2.4 可靠传输机制
- 序号 + 确认(ACK):每个字节都有序号,接收方确认已收到。
- 超时重传:RTT 动态计算(RTO)。
- 快速重传:收到 3 个重复 ACK 立即重传,不必等超时。
- SACK(选择性确认):告诉发送方哪些收到了,只重传丢失的。
- 滑动窗口:实现流量控制,接收方通过窗口大小告知能收多少。
- 累积确认:ACK=n 表示 n 之前的所有字节都收到了。
2.5 流量控制与拥塞控制
- 流量控制:防止发送方压垮接收方,靠滑动窗口 + 零窗口探测。
- 拥塞控制:防止压垮网络,四个算法:
- 慢启动:cwnd 从 1 开始指数增长(每 RTT 翻倍)到阈值。
- 拥塞避免:超过阈值后线性增长(+1/RTT)。
- 快重传:3 个重复 ACK 立即重传。
- 快恢复:ssthresh 减半,cwnd 从新阈值开始(不用回到 1)。
- 超时重传时 cwnd 回到 1,重新慢启动。
Nagle 算法:把小包攒起来一起发,减少网络开销,但会增加延迟(配合 TCP_NODELAY 关闭)。常见于对延迟敏感的 RPC。
2.6 TCP 粘包与拆包
- TCP 是字节流,没有消息边界,多次 send 可能被合并(粘包)或拆分。
- 解决:① 固定长度;② 分隔符(如
\n);③ 长度前缀(最常用,如 4 字节长度 + 数据)。 - 本质是应用层要自己定义消息边界,UDP 无此问题(保留边界)。
3. HTTP 协议
3.1 HTTP 方法
| 方法 | 语义 | 幂等 | 安全 |
|---|---|---|---|
| GET | 获取资源 | 是 | 是 |
| POST | 创建资源 | 否 | 否 |
| PUT | 全量更新(不存在则创建) | 是 | 否 |
| PATCH | 部分更新 | 否 | 否 |
| DELETE | 删除 | 是 | 否 |
| HEAD / OPTIONS | 获取头 / 预检 | 是 | 是 |
幂等=同一请求执行多次结果相同(网络重试安全)。
3.2 状态码
| 码 | 含义 |
|---|---|
| 200 / 201 / 204 | 成功 / 已创建 / 无内容 |
| 301 / 302 | 永久重定向(浏览器缓存)/ 临时重定向 |
| 304 | Not Modified,协商缓存命中 |
| 400 / 401 / 403 / 404 | 参数错 / 未认证 / 无权限 / 不存在 |
| 405 / 429 | 方法不允许 / 请求过多(限流) |
| 500 / 502 / 503 / 504 | 服务器错 / 网关错(Bad Gateway) / 不可用 / 网关超时 |
502 vs 504:502 是上游返回了非法响应或连不上;504 是上游响应超时。都说明 Nginx 到后端这条链路有问题。
3.3 HTTP 版本演进
| 版本 | 关键特性 | 问题 |
|---|---|---|
| 1.0 | 每请求一个连接 | 连接开销大 |
| 1.1 | 长连接 keep-alive、管道化、Host 头 | 队头阻塞(应用层)、头部冗余 |
| 2.0 | 多路复用(二进制分帧)、头压缩 HPACK、服务器推送 | TCP 层队头阻塞(丢包影响所有流) |
| 3.0 | 基于 QUIC/UDP,0-RTT,无 TCP 队头阻塞 | 兼容性、中间设备 |
3.4 HTTP 缓存
- 强缓存:
Cache-Control: max-age=3600(优先级高于 Expires),命中则不发请求。 - 协商缓存:
Last-Modified/If-Modified-Since或ETag/If-None-Match,命中返回 304。 - ETag 优于 Last-Modified:精度更高(秒级 vs 内容哈希),且能识别"内容未变但修改时间变了"。
no-cache= 可缓存但每次要验证;no-store= 完全不缓存。
3.5 Cookie / Session / Token
- Cookie:客户端存储,每次请求自动带上;可设 HttpOnly(防 XSS 读取)、Secure、SameSite(防 CSRF)。
- Session:服务端存状态,Cookie 只存 sessionId;有状态,集群需共享(Redis)。
- JWT:无状态,
header.payload.signature,签名防篡改但不可撤销、payload 仅 base64 可读。 - 跨域 CORS:浏览器同源策略限制;简单请求直接发,复杂请求先 OPTIONS 预检。
4. HTTPS 与 TLS
4.1 为什么需要 HTTPS
- 机密性:对称加密传输数据。
- 完整性:MAC/签名防止篡改。
- 身份认证:证书验证服务器身份,防中间人。
4.2 TLS 握手(RSA 与 ECDHE)
- 客户端发 ClientHello(支持的 TLS 版本、密码套件、随机数 A)。
- 服务端回 ServerHello(选定套件、随机数 B)+ 证书。
- 客户端验证证书(CA 链、有效期、域名),生成 Pre-Master Secret,用证书公钥加密发送。
- 双方用三个随机数生成会话密钥(对称),之后用对称加密通信。
为什么用对称加密传数据、非对称加密传密钥?——非对称加密性能差(约慢千倍),对称加密快;但对称密钥不能明文传输,故用非对称加密安全交换。
TLS 1.3 改进:握手压缩到 1-RTT(甚至 0-RTT 恢复),废弃 RSA 密钥交换只用 ECDHE(前向安全:私钥泄露也不能解密历史流量),只保留 AEAD 加密套件。
4.3 证书与 CA
- 数字证书:CA 用自己的私钥对"服务器公钥 + 域名 + 有效期"签名。
- 客户端用 CA 的公钥(内置在系统/浏览器)验证签名,形成信任链。
- 证书链:根证书 → 中间证书 → 服务器证书。
- 自签名证书浏览器会警告(不在信任链中)。
5. DNS 与网络排查
5.1 DNS 解析过程
- 浏览器缓存 → 系统缓存 → hosts 文件。
- 本地 DNS 服务器(递归查询)。
- 本地 DNS 依次问 根域名服务器 → 顶级域(.com) → 权威域名服务器,拿到 IP 返回。
记录类型:A(IPv4)、AAAA(IPv6)、CNAME(别名)、MX(邮件)、NS(域名服务器)、TXT。
DNS 用 UDP 53(查询),响应超长时用 TCP;区域传送用 TCP。
5.2 常用排查工具
| 工具 | 用途 |
|---|---|
| ping | 测试连通性与 RTT(ICMP) |
| traceroute | 逐跳跟踪路由 |
| netstat / ss | 看端口监听与连接状态(ss -lntp) |
| tcpdump | 抓包分析(tcpdump -i eth0 port 80) |
| curl -v / -I | 看请求响应全过程 / 只看响应头 |
| dig / nslookup | DNS 查询 |
| mtr | ping + traceroute 结合,持续观察丢包 |
5.3 常见问题定位
| 现象 | 可能原因 |
|---|---|
| Connection refused | 端口没监听 / 防火墙 reject |
| Connection timeout | 防火墙 drop / 路由不通 / 服务假死 |
| ping 不通但能连 | ICMP 被禁,不代表网络不通 |
| DNS 解析慢 | DNS 服务器慢 / 未配缓存 / 走了 IPv6 超时 |
| 偶发 502 | 后端 GC 停顿 / 连接池耗尽 / 上游超时 |
6. 速查清单
| 主题 | 一句话答案 |
|---|---|
| TCP vs UDP | 可靠有序有连接 vs 不可靠无连接快 |
| 三次握手 | 防历史失效连接;双方确认收发能力 |
| 四次挥手 | 全双工,被动方可能还有数据要发,ACK 与 FIN 不能合并 |
| TIME_WAIT | 等 2MSL 保证 ACK 到达 + 旧报文消散 |
| CLOSE_WAIT 多 | 应用没 close,是 bug |
| 快速重传 | 3 个重复 ACK 立即重传 |
| 拥塞控制 | 慢启动 → 拥塞避免 → 快重传 → 快恢复 |
| 流量控制 | 滑动窗口防压垮接收方 |
| 粘包 | 字节流无边界,用长度前缀/分隔符解决 |
| HTTP/2 | 多路复用、头压缩,但仍有 TCP 队头阻塞 |
| HTTP/3 | QUIC/UDP,解决队头阻塞,0-RTT |
| 强缓存 | Cache-Control max-age,命中不发请求 |
| 协商缓存 | ETag/Last-Modified,命中返回 304 |
| HTTPS | 非对称换密钥 + 对称传数据 + 证书认证 |
| TLS 1.3 | 1-RTT、ECDHE 前向安全 |
| 502 vs 504 | 上游非法响应 vs 上游超时 |
| CORS | 同源策略,复杂请求先 OPTIONS 预检 |