按下回车到网页显示:DNS、TCP/IP、ARP与HTML渲染全链路拆解

发布时间:2026/10/23 6:05:43
按下回车到网页显示:DNS、TCP/IP、ARP与HTML渲染全链路拆解 很多人学网络协议都是分模块啃的DNS是DNSTCP是TCPARP是ARP学完感觉都懂但一旦被问到“小明在家按了下回车网页是怎么出来的”就卡住了。这篇文章就把这个经典场景完完整整拆一遍从浏览器里敲下网址那一刻开始到网页渲染完毕中间涉及DNS缓存、DNS查询、TCP/IP协议、ARP协议、HTML渲染这几条线全部串成一条可复现的链路。配合抓包思路和排障经验适合正在学计算机网络、或者工作里经常要排查网络问题但知识不成体系的朋友。1. 先看全局按下回车那一刻网络里有哪些角色在干活1.1 家庭网络中的参与方要理解一次完整的网页访问第一步不是钻进协议细节而是先把“当事人”都拉出来。小明的家用网络拓扑其实很简单参与这次访问的角色包括浏览器负责发起HTTP请求、解析服务器返回的HTML资源、最终渲染页面。操作系统提供Socket接口、维护DNS缓存、组织TCP报文并让数据包进入网卡队列。网卡与设备驱动把IP数据包封装成以太网帧通过Wi-Fi或有线网线发出去。家庭路由器充当网关负责把家庭内网的数据包转发到运营商网络同时承担NAT地址转换。运营商侧的接入设备把来自用户家庭的数据汇聚进城域网和骨干网。DNS解析服务把域名翻译成IP地址可以是运营商提供的DNS也可以是用户手动配置的公共DNS。目标网站服务器处理收到的HTTP请求把网页资源返回给客户端。每个角色只完成自己那一小段工作然后把结果交给下一个环节。这就像工厂流水线没人需要知道整个产品的全部工序每个人只要把手上那份活干好就行。1.2 一整套协议栈的分工一次访问里涉及的协议远不止标题里那几个关键词。按TCP/IP分层模型来看它们各司其职层次涉及协议这一层干的事生活类比应用层HTTP/HTTPS、DNS定义客户端和服务器之间的语义比如“我要获取某个资源”顾客和服务员沟通“我要点一份红烧肉”传输层TCP把数据切成段、编号、确认保证可靠有序交付快递公司保证包裹不丢、不破、按顺序送到网络层IP、ICMP为数据包寻址决定从源到目的走哪条路快递单上的地址让包裹知道往哪个城市寄链路层以太网、ARP把数据封装成帧通过物理介质发送给下一个设备快递员按门牌号把包裹送到具体人家这里面最容易被忽视的关系是HTTP本身根本不关心网络通不通TCP也不关心设备之间用Wi-Fi还是网线只有到了链路层ARP和以太网帧才管“物理上怎么把数据传出去”。所以标题把这几层协议放在一起讨论是有道理的因为一次访问要打通的是整条链路缺任何一环都不行。2. DNS缓存的金字塔每次打开网址第一个环节怎么跑2.1 浏览器和操作系统层面的缓存优先级小明在地址栏输入www.demosite.net虚构示例并按回车以后浏览器做的第一件事并不是发网络请求而是先在自己的内存里找缓存。这个缓存就是DNS缓存键值对形式最常见的是www.demosite.net - 203.0.113.88浏览器有缓存操作系统也有一份缓存而且操作系统缓存往往是浏览器缓存之后的第二道防线。在Windows上这是DNS Client服务在维护在Linux上通常是systemd-resolved或nscd在做这件事。为什么要设计成两层缓存因为DNS查询本质上是去别的机器上问问题一次查询要跨越局域网、城域网甚至跨洋哪怕只要几十毫秒累积起来也很可观。而本地缓存把命中结果的时间压缩到微秒级——从内存里直接查表比任何网络往返都快。这里有个实际经验改完DNS服务器地址以后明明配置生效了但域名解析还是老结果八成就是缓存没刷新。Windows上用ipconfig /displaydns可以看到操作系统里的完整DNS缓存表确认你查的那个域名还挂着旧IP。2.2 全部缓存未命中时一次完整的DNS递归查询如果浏览器、操作系统层面都没有缓存查询就要被发到“外部世界”。小明的设备会把请求发给本地DNS服务器——这里的“本地”不是指小明的电脑而是指运营商或用户配置的上游DNS服务。这个请求是递归查询意思是小明对本地DNS说“帮我彻底查清楚这个域名到底指向哪个IP别让我再管后续了。”本地DNS服务器拿到请求后会分几步做迭代查询先问根DNS服务器“www.demosite.net 的IP是什么”根服务器不会直接给出答案但会告诉它“这个域名属于.net顶级域你去问.net顶级域服务器。”再去问**.net顶级域服务器**“这个域名的权威服务器是谁”得到答复“权威服务器是 ns1.demosite.net。”最后问权威DNS服务器“www.demosite.net 的IP是什么”这回拿到了真正的答案203.0.113.88。本地DNS拿到这个结果后会先把结果缓存起来同时把答案返回给小明。这个过程用文字描述显得很长实际耗时通常只有几十到一两百毫秒——因为根和顶级域服务器的数据在本地DNS上一般是长期缓存的不是每个域名都要完整走一遍。2.3 缓存的保质期由TTL决定为什么有时候换个域名解析记录全球生效要等很久关键在TTL生存时间。每条DNS记录都带着TTL单位是秒表示“这条记录可以被缓存多久”。如果权威服务器设置了600秒那么途中所有缓存设备都会在10分钟内复用这个结果而不重新询问。TTL太短权威服务器压力大TTL太长记录更新太慢。常规做法是把基础记录的TTL设为3600秒左右做迁移前24小时调低到300秒迁移完再调回去。这个思路其实也适用于理解“为什么小明第二次打开同一个网站会明显变快”——因为缓存命中了。2.4 路由器上的DNS逻辑并不一定都有缓存很多家用路由器本身并不缓存DNS响应它们只做转发把内网设备的DNS请求通过网络地址转换转发到上游运营商DNS。但也有不少路由器带有轻量DNS代理功能会短暂记住前一次请求的结果。不管路由器有没有缓存小明电脑上DNS查询的目标默认都是路由器分配的DNS地址。这个地址通常来自运营商但也可以手动改成公共DNS。需要留意的是改电脑上的DNS指向并不影响“从权威服务器到本地DNS”这条链路的解析质量。如果你的路由器本身已经做了某些重定向那电脑改什么都没用这个细节在排查DNS问题时经常是隐藏难点。3. TCP连接三次握手、一个请求和断开时的四个动作3.1 三次握手不是形式主义DNS解析拿到目标服务器的IP地址后浏览器就要发起HTTP请求了。HTTP/1.1时代每个请求几乎都要新建一条TCP连接而TCP连接的第一个动作就是三次握手。假设服务器监听在80端口小明这边发出第一个报文小明 → 服务器SYNseq x。意思是“我想建连接我的初始序号是x。”服务器 → 小明SYNACKseq yack x1。意思是“确认收到你的序号x我的初始序号是y。”小明 → 服务器ACKseq x1ack y1。意思是“确认收到你的序号y连接正式建立。”为什么一定要三次核心原因是防止失效的连接请求突然到达服务器导致服务器白白建立资源。如果一个历史遗留的SYN报文滞留在网络里晚到服务器处服务器回复SYNACK后客户端如果发送的是RST而不是ACK那这次握手就会中止——三次握手中的第三次不仅是确认更是让服务器确认“客户端确实在线上”。实际排障时我用Wireshark看过太多次握手只完成一半的情况客户端发出SYN服务器没回SYNACK或者回了以后客户端没有发出ACK。前者多半是防火墙拦截了SYN后者则要考虑客户端连接池状态问题。3.2 握手完成后HTTP请求出门数据开始分段三次握手完成小明就开始发HTTP请求GET /index.html HTTP/1.1 Host: www.demosite.net User-Agent: Mozilla/5.0 ... Accept: text/html这串字符会作为TCP的载荷被加上TCP头源端口、目的端口、序列号后再交给IP层封装进IP数据包。数据太大时TCP会按MSS最大报文段大小把它切成多段每段都有自己的序号接收方按序号重组缺哪一段就重传哪一段。很多人把TCP的可靠性简单理解成“丢了就重传”但实际机制是接收方每收到一个段就返回一个ACK发送方如果发现超时没收到ACK会主动重传。这个超时时间不是固定的而是根据RTT动态计算出来的。这也解释了一个场景跨地域访问时TCP握手时间变长、下载速度下降不完全因为带宽不够更可能是RTT变大导致拥塞控制窗口增长速度变慢。3.3 IP和路由数据包怎么一路走向目标服务器这里必须补IP层的戏份。TCP报文交给IP层以后IP层要做的不是打包“发送”而是决定下一跳是谁。小明的电脑查看路由表发现目标IP203.0.113.88不在本地网段于是标记“下一跳是默认网关”也就是家庭路由器的内网IP。这个决策过程叫“最长前缀匹配”每个路由器都用同一套逻辑不断接力把包一路转发过去。IP协议本身不保证不丢包不保证不乱序这些事TCP负责IP只保证一件事数据包上有源地址和目标地址沿途设备都知道该怎么尽量把它送到。从家用路由器出去以后数据会经过运营商接入设备、城域网节点、骨干网出口再到服务器所在的数据中心交换机。这一路上的设备都在做类似的查表转发动作只不过它们的路由表比小明家路由器的复杂几个数量级。3.4 断开连接四次挥手、RST与Keep-Alive的真相小明拿到需要的页面内容以后连接怎么断开教科书里讲的是四次挥手一方发FIN另一方回ACK然后反过来再FINACK最后一轮ACK关闭。实际情况远没有那么理想——大多数浏览器访问网页后会主动保持连接因为同一个页面上还有CSS、JS、图片需要继续加载这就引出了HTTP Keep-Alive。但即使Keep-Alive连接最终也会被某个机制关闭常见的是服务器空闲超时断开或者客户端主动RST。RST是个被低估的报文它并不走四次挥手流程而是直接异常终止。比如我遇到过一种典型情况客户端请求的响应太大服务器已经设置了max header size限制直接发了RST客户端只看到“Connection reset by peer”这种情况靠抓包才看得出是应用层行为导致的复位。4. ARP协议同一个局域网里的“找MAC地址”广播4.1 IP地址之外网卡还需要什么很多人在网络层和链路层的分界上栽过跟头数据包明明有IP地址为什么还需要额外的协议来确定“发给谁”因为IP地址是逻辑地址它描述的是“这台机器在网络里的身份”但实际在同一个局域网里传输数据时网卡之间通信靠的是MAC地址。MAC地址是出厂时就烧在硬件上的物理唯一标识局域网设备之间根本不认识IP它们只认MAC。所以从一台设备向另一台设备发送以太网帧之前必须先知道对方网卡的MAC地址这一步就交给ARP协议。4.2 家庭局域网里的两种典型ARP场景场景一小明访问的目标是外面的服务器。这时ARP要解析的不是远端服务器而是小明和路由器之间的那个网关。小明的电脑通过路由表得知下一跳是家里的路由器比如192.168.1.1但它不知道路由器的MAC地址于是发出ARP广播“192.168.1.1的MAC地址是什么”路由器收到广播后单播回复“我就是我的MAC是xxx。”随后小明就把数据帧的目标MAC填成路由器的MAC往出扔。场景二小明访问的是路由器管理页面比如192.168.1.1。这时ARP解析的目标就是路由器本身。如果网络里有一台打印机的IP被手动改成和路由器的IP冲突ARP会解析到哪个MAC就不一定了这也是偶尔出现“打开路由器管理页却出来一台打印机设置页”的原因——因为ARP缓存表里那个IP对应的MAC已经变了。4.3 ARP缓存和局域网安全防护ARP广播不能太频繁所以每台设备内部都有ARP缓存表。在Linux上查看ip neigh show在Windows上是arp -a缓存表里的条目也会过期所以如果换了路由器、改了网关IP局域网设备短时间内可能解析到旧地址这就是“交换机/路由器都换了但设备还是连不上”的常见原因清一下ARP缓存就好了。另外一个不能回避的话题是ARP安全问题。ARP协议本身没有身份校验局域网里任何一个设备都可以声称“我就是网关”把发给网关的数据包骗走——这就是ARP欺骗。我家里就把路由器的静态ARP绑定做过一遍这是最简单的防护手段。在企业网络里还会有专门的动态ARP检测但家用网关上绑定MAC和IP对付绝大多数情况已经够了。5. 服务器响应之后浏览器如何把HTML渲染成页面5.1 从响应字节流到DOM树服务器收到小明的GET请求后返回一坨text/html字节流。浏览器拿到数据后连字符编码都没法定死因为HTML里可能写明charset但也可能依赖HTTP头。确定编码后字节流被切分成一个个token再按HTML语法规则组装成节点最后构造成一棵DOM树。这里有一个新手不太理解的点DOM不是因为页面好看才存在它是浏览器内部对HTML文档的结构化表示JS脚本能通过DOM API操作页面浏览器的渲染引擎也是基于它工作的。这个阶段一旦遇到语法错误浏览器并不会直接崩溃而是通过“错误恢复机制”尽力解析下去——HTML规范里专门写了各种错误怎么处理这一点和XML“报错就不生”的哲学完全不同。5.2 CSS和DOM结合渲染树、布局和绘制CSS字节流经过类似的过程变成CSSOM树描述每个元素的样式。DOM树和CSSOM树合并成渲染树但渲染树不是简单把两者拼起来它只包含“会真正显示到页面上的节点”——比如display: none的元素就不会进渲染树而visibility: hidden的元素虽然看不见但还占着空间会进渲染树。接下来是布局浏览器要计算每个节点在视口里的几何坐标。这里有个容易误导人的概念你以为CSS写的是“宽度10px”实际布局引擎处理的是大量相互影响的约束计算特别是flex、grid这种现代布局在计算过程中可能要多次回溯调整。然后进入绘制阶段浏览器把每个节点绘制成位图层。这里要点名一个性能关键概念绘制不是全局重头来一遍而是分层的。每个图层有自己的纹理合成器再把所有图层像叠相片一样拼到屏幕上。这也是为什么transform和opacity动画往往比修改top、left动画更流畅——因为前者直接在合成阶段处理不需要重新布局和绘制。5.3 JavaScript对渲染路径的干扰渲染流程中最容易被“卡住”的环节是JavaScript。浏览器解析HTML时碰到script标签如果是普通的同步脚本会立刻停下来先下载并执行完脚本再继续解析后续HTML。所以脚本放head里会导致页面首屏的时间明显变长。解决办法不外乎两种把script标签放在body底部或者给脚本加上defer或async。但两者有区别defer保证执行顺序与文档顺序一致适合有依赖的多个脚本async则下载完就执行谁先到谁先跑适合独立的统计脚本、广告脚本。我自己实测过同样的页面结构把三个同步脚本改成defer首屏时间能缩短几百毫秒在慢速移动网络上差距更明显。6. 从这条链路反推排障思路页面打不开时问题最可能出在哪6.1 沿着协议链路快速定位故障环节搞懂整条链路以后最大的收益不是“会背协议”而是“遇事知道先查什么”。故障现象最可能出问题的环节第一反应输入IP可以访问但输域名不行DNS解析本机DNS缓存、本地DNS服务器、域名托管商的解析记录域名解析正常但TCP一直转圈网络层连接防火墙拦截、路由不可达、目标服务器拒绝连接浏览器提示证书错误TLS握手证书链不完整、日期不对、域名不匹配首屏白屏但curl能拉到HTML渲染资源加载JS执行错误、CSS阻塞、资源路径404打开很慢但最终能打开内核协议栈参数或链路质量RTT太高、MTU分片、MSS不一致这个表格是我平时最快的一个排查框架。比如“输入IP能开、域名不行”这件事直接用nslookup看解析结果就能确认是不是DNS层面的问题nslookup www.demosite.net如果返回了正确的IP但浏览器还是打不开那问题可能在本机缓存或HSTS浏览器强制HTTPS上这时候就要换个端口/换一个隐身窗口来排除浏览器端干扰。6.2 一个典型的“能打开但很慢”的排查过程我遇到过类似情况小明访问网页能成功但首屏要等好几秒。打开浏览器开发者工具的Network面板发现一个CSS文件耗时2.8秒。问题出现在哪链路反过来排查curl直接拉这个CSS文件本地测很快那问题就不在服务器。再看Network面板浏览器对该资源的加载是排队状态——原来是页面里有两三百张小图片每个都单独发HTTP请求同一时刻浏览器对同一域名只能开有限的N条连接大头全被图片请求占住了。这种问题常见的解法是域名分片或者开启HTTP/2多路复用。如果服务器支持HTTP/2同一个连接上可以并发传输多个资源排队问题就能缓解大半。我当时的处理是把静态资源移到某个支持HTTP/2的CDN前面问题直接消失。也有另一种情况curl能秒开浏览器很慢但Network面板里资源全都正常。这时要把注意力转到渲染链路上看是不是JS在DOMContentLoaded之后做了大量同步计算导致渲染进程被阻塞。打开Performance面板录制一次加载是最快的定位方式。6.3 排障过程中最容易忽略的三个细节第一IPv6优先级。如果你访问的域名同时有A记录和AAAA记录而家庭网络的IPv6连通性有问题操作系统可能一直尝试IPv6、超时后再退回IPv4白白浪费几秒。排查时可以直接关掉系统IPv6看问题是否消失。第二路由器的MTU分片陷阱。家用宽带默认MTU通常控制在1500但如果PPPoE拨号让链路MTU变小了而两边没有正确协商MSS就可能出现小包通、大包不通的诡异现象网页能开但下载大文件卡死。这时候可以手动调低路由器WAN口的MTU到1492顺带打开MSS Clamp。第三别一上来就上抓包工具。排查大部分问题先用浏览器开发者工具和curl -v就够了。Wireshark适合抓本地环境的问题比如ARP欺骗、TCP重传、异常RST但看到一堆乱糟糟的报文之前你得先确定自己到底在查哪一层的问题。我见过太多人开着Wireshark不知道该过滤什么等我把问题定位到HTTP层时他还在逐条翻TCP重传。从DNS缓存到HTML渲染这条链路我拆完以后再回过头看那个按了一次回车的“小明”感觉就像看了一场默剧——每个角色都在自己的位置上安静地工作没有谁特别重要但没有谁可以缺席。我自己在工作里排查网络问题时最依赖的就是这套整体视角建议你也试着把知识按“数据从哪来到哪去”的主线重新串一遍会比死记协议字段有用得多。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询