【计算基础|网络01】网络模型与一次完整请求全景

【计算基础|网络01】网络模型与一次完整请求全景

"在浏览器地址栏敲一个网址回车,到页面画出来,中间到底发生了什么?"------这道题几乎是所有后端、运维、前端面试的开场必问题。答得碎、答得散,说明你脑子里没有一张"全景图";答得成体系,你后续排查任何网络问题(连不上、超时、被劫持、慢)都知道该从哪一层下手。

这篇不堆协议名词,先把分层模型这张地图立起来,再顺着这张地图走一遍"从 DNS 到渲染"的完整请求,最后落到 Linux 内核里一个网络包是怎么被收上来的。这是整个网络系列的地基:后面 02 篇讲 HTTP 报文、05 篇讲 HTTP/2、HTTP/3,全部建立在"请求在哪一层、用什么协议、包怎么流"这个框架上。

环境:macOS 本机 + 任意一台 Linux 服务器(内核收包流程以 Linux 为例),命令用 dig/curl/ss 实测,均为系统自带或常见工具。


一、为什么要分层:先把地图立起来

结论先给:分层的本质是"关注点分离"------每一层只干自己那一段的事,对上提供服务、对下透明。 你写应用代码不用关心网线、电磁波;网卡驱动也不用关心你发的是 HTTP 还是 Redis。分层让几百个厂商、几十年的技术能拼在一张网上跑。

1.1 OSI 七层 vs TCP/IP 四层

业界两套模型:OSI 七层是"理论教材",TCP/IP 四层是"真实互联网跑的那套"。对着记,别死背:

OSI 七层 TCP/IP 四层 各层职责(一句话) 典型协议/设备
应用层 应用层 给应用程序用的协议,直接面对你写的代码 HTTP/HTTPS、DNS、SSH、FTP、Redis
表示层 应用层 编解码、加密、压缩(TLS 握手、JSON 序列化算在这里) TLS/SSL、UTF-8、Protobuf
会话层 应用层 建立/管理/断开会话 (现代基本并入应用层)
传输层 传输层 端到端通信,负责可靠/不可靠、端口、流量控制 TCP、UDP
网络层 网络层(网际层) 点到点路由,选路,IP 寻址 IP、ICMP、ARP(算这层下沿)、路由器
数据链路层 链路层(网络接口层) 同一局域网内帧的传输,MAC 寻址、差错检测 以太网、MAC、交换机
物理层 链路层 电信号/光信号/无线比特流 网线、光纤、集线器、网卡物理部分

🔴 重点:别被"七层/四层"绕晕,真正要刻进脑子的是三个分界:

  1. 传输层 = 端口:一台机器上跑着好几个服务(80、443、6379),靠端口区分,这是"进程到进程"。
  2. 网络层 = IP:把数据从这台机器送到那台机器,跨网段靠路由,这是"主机到主机"。
  3. 链路层 = MAC:只在同一个局域网(同一个广播域)内管用,出了局域网就靠路由器重新封装。

记住这三层,面试"一次请求在哪一层"你就不会错。

1.2 封装与分用:数据是怎么一层层套壳又一层层剥开的

结论:发送时从上往下,每经过一层就加一层"信封头"(封装);接收时从下往上,每经过一层就剥掉自己那层的头(分用/解封装)。 这就是"协议栈"三个字的来源------一层套一层的栈。

每一层加的"头"里装着这一层要用来干活的关键信息:

层 加的头叫啥 头里最关键的字段 这层靠它干嘛
传输层(TCP) TCP 段头 源端口、目的端口、序号、确认号、标志位(SYN/ACK/FIN) 找到对应进程、保证可靠、流控
网络层(IP) IP 数据报头 源 IP、目的 IP、协议号(6=TCP, 17=UDP, 1=ICMP) 跨网路由、知道该往上交给 TCP 还是 UDP
链路层(以太网) 帧头/帧尾 源 MAC、目的 MAC、类型(0x0800=IP)、FCS 校验 局域网内找到下一跳、校验完整性

⚠️ 一个容易混淆的点 :封装到 IP 头这一步,"下一跳的 MAC"不一定是最终目的主机的 MAC。IP 地址一直是最终目标不变,MAC 地址每经过一个路由器就换一次------这就是"IP 端到端、MAC 逐跳"。理解了这点,再去看 ARP、VLAN、隧道就通了。


二、键入网址到页面显示:走一遍完整流程

这是本篇的主干。把"敲回车"拆成下面 8 步,每一步我都标了它在哪一层、用什么协议,你照着这张表背,面试就不会漏。

2.1 全景时序图

2.2 逐步拆解(附协议与所在层)

步骤 发生了什么 所在层 用到的协议/工具
① DNS 解析 把 www.example.com 翻译成 IP。先查浏览器缓存 → 系统缓存 → hosts → 本地 DNS 递归 应用层 DNS(UDP 53,区域传送用 TCP)
② 建 TCP 连接 三次握手,确认双方收发能力正常 传输层 TCP
②.5 TLS 握手 HTTPS 才走:协商加密套件、交换密钥、验证证书 表示层/应用层 TLS/SSL(443)
③ 发 HTTP 请求 把请求行+请求头+空行+体交给 TCP 应用层 HTTP/1.1、HTTP/2、HTTP/3
④ 服务器处理 内核收包 → 交给 Web 进程 → 查业务逻辑/数据库 → 生成响应 应用层 Nginx/应用框架/数据库
⑤ 回 HTTP 响应 状态行+响应头+空行+体,按原路径封装回来 应用层 HTTP
⑥ 浏览器渲染 解析 HTML 构 DOM、CSSOM,布局、绘制,再对 JS/CSS/图片重复发子请求 应用层 HTML/CSS/JS、HTTP
⑦⑧ 断开连接 四次挥手(或 Keep-Alive 一段时间后再关) 传输层 TCP

🔴 高频追问 :DNS 为什么用 UDP?因为 DNS 查询通常很小、要快,UDP 省掉三次握手的开销;但区域传送(传整份域名记录)或响应超过 512 字节时会改用 TCP,别一刀切说"DNS 只用 UDP"。

2.3 实测一把:看浏览器/系统到底干了啥

不写代码,用命令把上面几步"看见"。先看 DNS:

bash 复制代码
# 本机直接问公共 DNS,看域名解析结果(macOS/Linux 都有 dig)
dig +short www.example.com
# 输出:
# 93.184.216.34

再看 TCP 连接和握手(-v 把过程打印出来):

bash 复制代码
# -v 会先打印 DNS/连接/TLS 阶段,再打印 > < 报文
curl -sv --http1.1 https://www.example.com -o /dev/null 2>&1 | grep -E "Trying|Connected|SSL|ALPN|HTTP|using"
# 输出(关键行):
# *   Trying 93.184.216.34:443...
# * Connected to www.example.com (93.184.216.34) port 443
# * ALPN: curl offers http/1.1
# * ALPN: server accepted http/1.1
# * SSL connection using TLSv1.3 / ...
# * using HTTP/1.x
# < HTTP/1.1 200 OK

你看,curl -v 的输出顺序,恰好就是上面那张表:先 Trying IP:port(这就是 DNS 的结果)→ Connected(TCP 三次握手完成)→ SSL ...(TLS 握手)→ > GET(发请求)→ < HTTP/1.1 200(收响应) 。线上排查"卡在哪一步",就是看它停在 Trying(DNS/路由问题)、Connected 之前(TCP 连不上)、还是 SSL 之后(应用层慢)。


三、TCP 三次握手与四次挥手:为什么是这个数

结论先给:三次握手是为了双方都确认"我能发、你能收,你能发、我能收";四次挥手是因为全双工下两个方向要分别关。

3.1 三次握手

🔴 为什么是三次不是两次 :两次握手,服务器收到 SYN 就建连接,但它没法确认客户端收到了自己的 SYN。更要命的是,一个历史迷路的旧 SYN 突然到了,服务器会误以为是新连接,白等资源。三次能让双方各发一次、各收一次,确认链路双向都通。

3.2 四次挥手

⚠️ 为什么挥手要四次、握手只要三次 :握手时服务器收到 SYN 可以一把把 SYN+ACK 合在一起发;挥手时,服务器收到 FIN 可能还有数据没传完,只能先回 ACK,等数据传完再单独发 FIN,所以 ACK 和 FIN 分成两步,变成四次。

⚠️ TIME_WAIT 是面试常考点 :主动关闭的一方要等 2MSL(报文最大生存时间的两倍,Linux 常约 60 秒)才彻底 CLOSED。目的有二:① 确保最后一个 ACK 能到对方(丢了对方会重发 FIN);② 让本轮连接的旧报文在网络里自然消散,避免污染下一个相同四元组的新连接。服务器上出现大量 TIME_WAIT,通常是因为服务器主动关连接(Nginx 配了短连接),不是 bug。


四、Linux 内核是怎么收一个网络包的

这是从"应用层视角"往下钻一层,也是后面讲性能优化、丢包排查的基础。结论先给:网卡收包不靠 CPU 主动去问,而是包到了网卡 → 网卡发硬中断告诉 CPU → 内核在软中断里跑协议栈逐层剥头 → 塞进 socket 缓冲区 → 应用进程 read 出来。

4.1 内核收包流程图

发送方向完全对称,只是顺序反过来:应用 write() → 进 socket 发送缓冲区 → 协议栈从上往下封装加头 → 软中断触发网卡发送 → DMA 把数据搬到网卡 → 推上网线。

🔴 几个关键认知:

  1. 硬中断要短 :硬中断期间 CPU 被占着、其他设备中断被阻塞,所以内核只做最紧急的"喊一嗓子",把重活丢给软中断 (下半部)慢慢干。这就是为什么高并发下看 top 里 si(softirq)占比高------网络包多,软中断忙。
  2. NAPI 是优化点 :包少时用中断来一个喊一个;包成批涌来时,硬中断通知一次后切换成 poll 模式批量收,避免"每来一个包都打断 CPU 一次"的中断风暴。万兆网卡、高 QPS 场景 NAPI 是标配。
  3. socket 缓冲区是个队列 :应用来不及 read,缓冲区塞满了,新到的包就只能丢------这就是"接收队列溢出导致丢包 ",ss -lnt 看到的 Recv-Q、丢包排查里的 RX drops 都跟它有关。

4.2 实测看一眼连接和缓冲区

bash 复制代码
# 看本机监听/连接,Recv-Q/Send-Q 就是那两个内核缓冲区
ss -lnt | head
# 输出大致:
# State   Recv-Q  Send-Q  Local Address:Port
# LISTEN  0       128           0.0.0.0:443
# LISTEN  0       128           0.0.0.0:80

Send-Q=128 是 listen 队列上限(backlog),Recv-Q 是当前已完成三次握手但还没被 accept() 取走的连接数------这个数涨满,新连接就会被拒(对应 SYN 队列溢出、listen() backlog 不够),这是线上常见的"偶发连不上"根因之一。


五、常见面试题:标准答案怎么组织

5.1 "输入 URL 后发生了什么"(标准答案结构)

别一上来就蹦名词,按这个时间线讲,逻辑就立住了:

  1. 解析 URL:拆分出协议(http/https)、域名、端口、路径、查询串。
  2. DNS 解析:查浏览器缓存 → 操作系统缓存 → hosts → 递归 DNS 服务器,拿到目标 IP。
  3. 建立连接:TCP 三次握手(HTTPS 紧接着 TLS 握手协商加密)。
  4. 发请求:封装成 HTTP 请求报文,交给协议栈逐层封装,过路由器逐跳转发。
  5. 服务器处理:内核软中断收包 → 协议栈剥头 → 到 socket → Web 进程处理业务 → 生成响应。
  6. 收响应:HTTP 响应逐层封装回来,浏览器按状态码处理(3xx 跳转、200 继续)。
  7. 渲染:解析 HTML 构 DOM/CSSOM,遇到 JS/CSS/图片再发子请求,布局绘制。
  8. 断开:四次挥手(或 Keep-Alive 复用连接)。

🔴 加分项:主动提到"中间还经过了 ARP(把下一跳 IP 解析成 MAC)、路由选路、NAT、CDN、负载均衡",并指出"HTTPS 的 TLS 握手是额外一轮延迟"。

5.2 "为什么要分层"

  • 各层独立、解耦:换网线不用改应用,换 HTTP 框架不用改网卡。
  • 标准化:每层定义清晰的接口和协议,不同厂商设备能互通。
  • 易于排障:出问题能定位到某一层(ping 不通多半是网络层及以下,curl 能连但返回错多半是应用层)。

5.3 "一次请求涉及哪些协议"

阶段 协议 干的事
域名 → IP DNS 名称解析
找下一跳 MAC ARP IP→MAC(局域网内)
跨网送包 IP + ICMP 路由、差错报告(ping 用它)
可靠传输 TCP 三次握手、序号确认、流控、拥塞控制
加密 TLS 密钥协商、证书验证、加密传输
应用语义 HTTP 请求方法、头、状态码、体

总结:你真正需要记住的 8 件事

  1. 三层分界:传输层管端口(进程)、网络层管 IP(主机)、链路层管 MAC(局域网逐跳)。
  2. 封装=从上往下加头,分用=从下往上剥头;IP 端到端不变,MAC 每跳都变。
  3. 一次请求主线:DNS 解析 → TCP 三次握手 → (TLS 握手)→ 发 HTTP 请求 → 服务器处理 → 收 HTTP 响应 → 浏览器渲染 → 四次挥手。
  4. 三次握手 是为了双向确认收发能力;四次挥手是因为全双工两个方向要分别关,且被动方可能还有数据要发。
  5. TIME_WAIT 等 2MSL:保证最后 ACK 可达 + 让旧报文消散,服务器大量 TIME_WAIT 通常是服务器主动关连接。
  6. Linux 收包:网卡 DMA → 硬中断(短)→ 软中断 poll → 链路/网络/传输层逐层剥头 → 挂到 socket 缓冲区 → 应用 read。
  7. 硬中断要短、重活放软中断;NAPI 在高负载下把中断改成批量 poll;socket 缓冲区满了就丢包。
  8. curl -v 的输出顺序就是请求全流程 :停在 Trying 查 DNS/路由,停在 Connected 前查 TCP/防火墙,过了 SSL 才到应用层。

验证清单

  • 能不看资料默写出 OSI 七层与 TCP/IP 四层的对应关系和各层协议
  • 能画出封装/分用图,并说清"IP 不变、MAC 逐跳变"
  • 能讲清三次握手和四次挥手的每一步,以及为什么握手三次、挥手四次
  • 能说出 TIME_WAIT 的两个作用和它在哪一方出现
  • 能用 dig +short 把一个域名解析成 IP,并用 curl -v 指出每一行对应流程的哪一步
  • 能描述 Linux 从网卡收到包到应用 read 出来的完整路径
  • 能解释硬中断为什么要短、软中断/NAPI 解决什么问题
  • 用 ss -lnt 看懂 listen 队列的 Send-Q,理解 backlog 溢出的后果

参考资源


下一篇《网络02:HTTP 原理------报文结构、方法语义与状态码》:把"应用层那封 HTTP 信"彻底拆开------请求行/请求头/空行/请求体到底长什么样,GET/POST/PUT/PATCH 谁安全谁幂等,1xx~5xx 状态码逐个速查,并对比 HTTP/1.0 与 HTTP/1.1 的关键区别,最后用 curl -v 抓一份真实可读的报文。

相关推荐
2501_933923251 小时前
SpringCloud:通过订单服务认识什么是微服务
spring boot·后端·spring cloud
小番茄程序猿1 小时前
RAG 的 precision 只有 0.55,我以为检索烂了,MRR 一测才发现是我用错了尺子
java·后端
llqbzllll1 小时前
MySQL 索引为什么会失效?用同一张表前后 EXPLAIN 定位原因
后端
程序猿_极客2 小时前
【免费】2026分享一套优质的基于Java的电子产品抢购管理系统的设计与实现(智能推荐算法+可视化图表),源码+文档+视频详解(讲解)
java·spring boot·后端·协同过滤·电子产品抢购系统
小羊没烦恼!2 小时前
Windows Azure Platform体验(1):Windows Azure
java·大数据·后端·python·flask·word·.net
墨天梦2 小时前
B15_HTTP解析与OkHttp拦截器
网络协议·http·okhttp
小小张说故事2 小时前
Python 装饰器到底是个啥?从 @ 符号到手写一个,5 个例子讲透
后端·python
CodeSheep2 小时前
朋友面试谈薪报价2w,HR非得压到1.9,还反问他:你就差这1000块钱?后来背调时问了他前同事十几个问题,对方最后直接挂了
前端·后端·程序员
徐小黑ACG2 小时前
Golang 基础02 控制语句
开发语言·后端·golang