目录
科普原理

打开一个网页时发生了什么?网络通信入门

从在浏览器里输入网址到页面出现,背后依次发生了 DNS 解析、TCP 三次握手、TLS 握手和 HTTP 请求响应。本文用一张时序图把每一步做了什么讲清楚。

最后更新:

在浏览器地址栏输入一个网址、按下回车,到页面完整出现,通常不到一秒。这一秒里,浏览器依次做了四件事:用 DNS 把域名换成 IP 地址 → 用 TCP 三次握手和服务器建立连接 → 用 TLS 握手商量好加密方式 → 用 HTTP 发出请求、取回网页。下面一步步拆开来看,文末用一张时序图把整个过程串起来。

先从寄信说起

上网传递信息,和寄一封重要的信非常像。想象你要给远方的朋友寄一封信,并等他回信:

  1. 查地址:你只记得朋友的名字,得先翻地址簿,查到他家的具体地址;
  2. 打电话确认:寄之前先打个电话,「我要给你寄信了,你在家吗?」「在,寄吧!」——确认双方都联系得上;
  3. 上锁:信里有隐私,你把信锁进一个箱子,和朋友约定好只有你们俩能打开的钥匙;
  4. 邮局分拣:箱子交给邮政系统,一路经过好几个邮局,每个邮局只看地址,决定下一站送到哪里;
  5. 对方收信:朋友收到箱子,用钥匙打开,读到你的请求;
  6. 回信:朋友按原路把回信寄回来,你拆开就看到了想要的内容。
插图:寄信的六个步骤——查地址簿、打电话确认、把信锁进箱子、沿途邮局分拣、对方开门收信、寄回回信
  1. ① 查地址DNS 解析:把域名换成 IP 地址
  2. ② 打电话确认TCP 三次握手:确认双方都能收发
  3. ③ 上锁、约定钥匙TLS 握手:协商加密,确认对方身份
  4. ④ 邮局分拣路由:每台路由器按目标 IP 转发
  5. ⑤ 对方收信HTTP 请求:「请把首页给我」
  6. ⑥ 寄回回信HTTP 响应:网页内容送回浏览器

打开网页的过程几乎一模一样,只是每一步都换成了网络协议,而且整个过程通常不到一秒:

寄信上网本文对应
朋友的名字域名(如 example.com)第一步
查地址簿,得到家庭地址DNS 解析,得到 IP 地址第一步
地址里的门牌号 + 房间号IP 地址 + 端口号下一节
打电话确认对方在家TCP 三次握手第二步
把信锁进箱子、约定钥匙TLS 握手,协商加密第三步
一路经过的邮局路由器「数据包怎么跨过几十个路由器」
信的内容和回信HTTP 请求和响应第四步

先认识两个概念:IP 地址和端口

互联网上的每一台设备都有一个 IP 地址,就像门牌号,数据包要靠它才能被送到正确的设备。光有门牌号还不够,一台服务器上可能同时运行着网站、邮件等很多程序,所以还需要 端口号 指明「交给这台设备上的哪个程序」,就像同一栋楼里的房间号:

  • 网站用的 HTTPS 默认是 443 端口,老式不加密的 HTTP 是 80 端口;
  • 你在地址栏里一般看不到端口号,是因为浏览器自动使用了默认端口。

所以,访问一个网站,本质上就是和「某个 IP 地址的 443 端口」进行通信。问题是:我们记住的是 example.com 这样的域名,而不是一串数字。这就需要第一步。

第一步:DNS 解析,把域名换成 IP 地址

DNS(域名系统)相当于互联网的「电话簿」,负责把域名翻译成 IP 地址。浏览器会按顺序找答案,找到就停:

  1. 浏览器自己的缓存:最近访问过的域名,直接用;
  2. 操作系统的缓存和 hosts 文件;
  3. DNS 服务器:通常是运营商或路由器提供的,也可以是公共 DNS。如果它也不知道,会替你逐级去问:先问根域名服务器「.com 归谁管」,再问 .com 的服务器「example.com 归谁管」,最后问 example.com 的权威服务器拿到真正的 IP 地址。

查到的结果会被缓存一段时间(由网站设置的 TTL 决定),所以同一个网站第二次打开时,往往就不用再查了。DNS 逐级查询的细节见 常见网络协议。

第二步:TCP 三次握手,确认双方都能收发

拿到 IP 地址后,浏览器要先和服务器「打个招呼」,建立一条 TCP 连接。TCP 负责保证数据完整、按顺序地送达,丢了会重传。建立连接需要来回三次,所以叫「三次握手」:

  1. 浏览器:「我想和你建立连接」(SYN);
  2. 服务器:「收到,我也准备好了」(SYN-ACK);
  3. 浏览器:「好,那我们开始吧」(ACK)。

为什么要三次?因为双方都需要确认自己发的对方能收到、对方发的自己也能收到。少一次,总有一方无法确认。

第三步:TLS 握手,商量好加密方式

网址以 https 开头时,在正式传数据之前,还要做一次 TLS 握手,目的是两件事:确认对方真的是这个网站,以及商量出一把只有双方知道的密钥。以现在主流的 TLS 1.3 为例:

  1. 浏览器发出 ClientHello:我支持哪些加密算法,并附上自己的密钥参数;
  2. 服务器回复 ServerHello:选定加密算法、附上它的密钥参数,同时出示证书;
  3. 浏览器验证证书:证书是不是由可信的机构签发、有没有过期、上面的域名对不对。验证通过后,双方各自用交换的参数算出同一把会话密钥(密钥本身从来没有在网络上传输过);
  4. 双方互发 Finished,确认握手过程没有被篡改。

从这以后,双方的通信内容全部用这把会话密钥加密。

第四步:HTTP 请求与响应,取回网页

连接和加密都准备好了,浏览器终于可以说出真正的目的:发出一个 HTTP 请求,例如「GET /,请把首页给我」,同时附上浏览器类型、语言、Cookie 等信息。服务器处理后返回 HTTP 响应:一个状态码(200 表示成功,404 表示找不到,500 表示服务器出错)和网页的 HTML 内容。

浏览器开始解析 HTML,发现里面还引用了图片、样式表、脚本,于是继续发出更多请求。一个普通网页往往需要几十上百个请求,它们会复用已经建立的连接,在 HTTP/2、HTTP/3 下还能同时并行传输。全部取回后,浏览器把它们组合起来,渲染出你看到的页面。

数据包是怎么跨过几十个路由器的?

上面每一步的数据,都被切成一个个数据包发出去。你的电脑和服务器之间并没有一根直达的网线,数据包要经过家里的路由器、运营商的机房、跨城甚至跨国的骨干网,中间往往有十几到几十台路由器。

每台路由器只做一件事:看数据包上的目标 IP 地址,查自己的路由表,把它转发给「离目标更近的下一站」。就像快递在每个分拣中心只决定下一站发往哪里,而不需要知道完整路线。

想亲眼看看这条路径,可以用系统自带的命令:

# macOS / Linux
traceroute example.com

# Windows(在命令提示符里运行)
tracert example.com

输出的每一行就是路上的一台路由器,后面的毫秒数是数据包到达那里再返回所需的时间。数值在某一跳突然变大,往往说明那一段线路比较拥堵或距离很远(比如跨海光缆)。

一张图总结全过程

下面把四个步骤放在同一张时序图里。左边是你的浏览器,中间是 DNS 服务器,右边是网站服务器;从上往下是时间顺序,粗线表示已经加密的数据:

浏览器 DNS 服务器 网站服务器 DNS 解析 example.com 的 IP 是多少? 1 返回 IP 地址 2 TCP 三次握手 SYN:我想建立连接 3 SYN-ACK:收到,我也准备好了 4 ACK:好,开始吧 5 TLS 握手 ClientHello:支持的算法 + 密钥参数 6 ServerHello + 证书 + Finished 7 验证证书、算出密钥 8 Finished 9 HTTP 请求与响应 GET /(已加密) 10 200 OK + 网页内容(已加密) 11 渲染页面 12
从上往下是时间顺序。粗线表示已经用会话密钥加密的数据。
步骤发生了什么为什么需要
① 查询 IP浏览器问 DNS 服务器:这个域名的 IP 是多少网络只认 IP 地址,不认域名
② 返回 IPDNS 服务器给出 IP 地址(必要时它会逐级去问根、顶级、权威服务器)拿到目的地的「门牌号」
③ SYN浏览器向网站的 443 端口发起连接请求开始 TCP 三次握手
④ SYN-ACK服务器确认收到,并表示自己也准备好了证明「浏览器 → 服务器」这个方向是通的
⑤ ACK浏览器确认收到服务器的回复证明「服务器 → 浏览器」这个方向也是通的,连接建立
⑥ ClientHello浏览器列出支持的加密算法,并发出自己的密钥参数开始 TLS 握手
⑦ ServerHello + 证书服务器选定算法、发出它的密钥参数和证书让浏览器能确认网站身份、算出密钥
⑧ 验证证书、算出密钥浏览器检查证书是否可信、是否匹配域名,并算出会话密钥防止连到冒充的网站;密钥不经网络传输
⑨ Finished浏览器确认握手完成(服务器的 Finished 已随 ⑦ 一起发出)确认整个握手过程没有被篡改
⑩ GET /浏览器发出加密的 HTTP 请求真正索取网页
⑪ 200 OK + 网页服务器返回加密的网页内容浏览器拿到 HTML
⑫ 渲染页面浏览器解析 HTML,继续请求图片、样式、脚本,最后渲染出页面你看到完整的网页

在正常网络下,①–⑨ 一共只需要几十到几百毫秒;如果服务器在海外,每一次来回都要跨越大洋,握手阶段就会明显变慢,这也是访问海外网站「打开慢」的主要原因之一。

相关阅读

常见问题

为什么第二次打开同一个网站更快?

很多步骤被省掉了:域名对应的 IP 已经缓存,不用再查 DNS;浏览器会复用之前建立的连接,TLS 也可以用「会话恢复」跳过大部分握手;图片、脚本等文件本身也被浏览器缓存在本地。

网址前面的 http 和 https 有什么区别?

https 多了 TLS 加密这一步。用 http 时,网页内容在网络上以明文传输,沿途的人都能看到甚至篡改;用 https 时,内容在你和网站之间是加密的。现在绝大多数网站都已经使用 https。

网页一直在转圈,怎么知道卡在哪一步?

在浏览器里按 F12 打开开发者工具,切到「网络」(Network)面板刷新页面,点开第一个请求看「时间」(Timing):DNS Lookup、Initial connection、SSL、Waiting for server response 分别对应本文的 DNS、TCP、TLS 和 HTTP,哪一段特别长,问题就在哪一步。

还没有安装穿山甲?

支持 iPhone / iPad、Mac、Windows 与 Android。新用户注册即送 7 天会员体验。

下载客户端
← 全部文章