敲下回车后都发生了什么

敲下回车后都发生了什么

某天在水群的时候看见了一句话"计网的几层也可以通过输入网址敲击回车后发生了什么串起来",刚好也在补基础,所以就窃取了灵感,学习一下计网的基础知识,顺便水一篇博客

每天我们都无数次通过浏览器这个通向全世界的窗口来上网冲浪,但鲜少有人注意当我们每次在地址栏输入网址,按下enter键后都发生了什么

浏览器解析URL

URL(同意资源定位符)是因特网中的唯一资源的地址。它是浏览器用于检索已发布资源(例如HTML页面,CSS文档,图像等)的关键机制之一。

理论上说,每个有效的 URL 都指向一个唯一的资源。

比如有这样一个URL:

https://www.example.com:443/path/index.html?name=alice#section

它可以拆成:

部分含义
https使用 HTTPS 协议
www.example.com目标域名
443端口号,HTTPS 默认 443
/path/index.html请求路径
?name=alice查询参数
#section页面内片段,不会发送给服务器

浏览器首先要弄清楚三件事:

  1. 用什么协议访问?
  2. 访问哪个主机?
  3. 请求哪个资源?

如果没有显式写端口,浏览器会根据协议补默认端口:

协议默认端口
HTTP80
HTTPS443

DNS解析

真正的网址看上去并不像你输入到地址栏中的那样美好且容易记忆。它们是特殊的数字,像 192.0.2.172

这串数字叫做IP地址,它代表的是web上独一无二的位置。然而,它并不容易记忆,不是吗?那就是发明域名系统(DNS)的原因。这个系统使用特殊的服务器将你输入到浏览器(如“mozilla.org”)的网址匹配到网站真实的(IP)地址。

当你输入www.example.com时,浏览器需要先知道这个域名对应哪个IP地址

DNS 查询通常会按下面顺序尝试:

  1. 浏览器 DNS 缓存
  2. 操作系统 DNS 缓存
  3. hosts 文件
  4. 本地 DNS 服务器
  5. 根 DNS 服务器
  6. 顶级域 DNS 服务器,比如 .com
  7. 权威 DNS 服务器

最终得到类似结果:

www.example.com -> 93.184.216.34

这一步主要用到的协议是DNS协议,跑在最顶端的应用层

DNS 一般使用 UDP 53 端口,但在响应过大、区域传输等场景下也可能使用 TCP。

判断目标 IP 在不在同一个网络

拿到 IP 后,主机会判断目标地址是否和自己处于同一个局域网。

假设本机信息如下:

本机 IP:192.168.1.100
子网掩码:255.255.255.0
默认网关:192.168.1.1
目标 IP:93.184.216.34

通过子网掩码判断后,发现目标 IP 不在本地局域网。

于是数据不能直接发给目标服务器,而是先发给默认网关,也就是路由器。

这里涉及几个概念:

概念作用
IP 地址标识网络中的主机
子网掩码判断两个 IP 是否在同一网段
默认网关访问外部网络时的下一跳
路由表决定数据包下一步发往哪里

这一阶段主要对应:

网络层次协议 / 概念
网络层IP、路由

为什么数据不能直接发给目标服务器呢?

我们先构建一个简单的网络:

当两台计算机需要通信的时候,你必须要连接他们,无论通过有线方式(通常是网线)或是无线方式(比如 WiFi 或蓝牙)。所有现代计算机都支持这些连接。

png1

通常一个网络不仅限于两台计算机。你可以尽你所想地连接计算机,但是情况立刻变得复杂了。如果你尝试连接,比如说十台计算机,每台电脑有九个插头,总共需要 45 条网线。

png2

为了解决这个问题,网络上的每台计算机需要连接到一个叫做网络交换机(network switch)的小型特殊计算机。交换机只干一件事:就像火车站的调度员,它要确保从一台计算机上发出的消息仅可以到达目标计算机。为了把消息发送给计算机 B,计算机 A 必须把信息发送给交换机,交换机将收到的信息转发给计算机 B。计算机 B 不会收到发给其他计算机的消息,发给计算机 B 的消息也不会传到局域网上的其他计算机上。

一旦我们把交换机加入到这个系统,我们的网络中便只需要十条网线:每台计算机一个插口,交换机上十个插口。

png3

网络中的网

到目前为止一切都很好。但是我们要连接成百上千、上亿台计算机呢?当然一台交换机覆盖不了这么远,但是,如果你阅读得比较认真,我们曾提到交换机像其他计算机一样,所以我们为什么不把两个交换机彼此连接呢?

png4

你可以想象我们可以无限地将交换机连接起来,形成这样的网络:

png5

但是在现实中,这样会导致许多工程问题。数据包需要经过的交换机越多,到达目的地的时间就越长。而且你不能只依赖这种树状结构的交换机集群,因为一旦某个交换机节点故障,就会导致大面积的断网,这会使你的网络变得脆弱。为了解决这个问题,我们将每个网络保持在一个较小的规模,并使用一种名为路由器(router)的设备来连接每个网络。路由器是一种负责在不同网络之间转发消息的计算机,其运作原理类似邮局:当数据包到达时,它会读取收件人的地址,直接将数据包转发给正确的收件人,而无需经过层层中转。

我们来解释一下上面这段话,

首先路由器比纯使用交换机好在哪:

首先,交换机工作在数据链路层(二层),转发依据是 MAC 地址。当一个设备想找到另一个设备时,它会发送广播帧(比如 ARP 请求),交换机必须把这个广播复制到所有端口。

如果只有几十台设备,广播影响可以忽略。但如果把全世界的设备都连成一个二层网络,任何一台设备发出的广播,都会瞬间扩散到整个地球。每一台设备都会不断收到海量与自己无关的广播,CPU 被占用,带宽被耗尽,这就是广播风暴。结果就是,全世界网络一起瘫痪。

其次,交换机靠 MAC 地址表来寻址,二路由器使用IP地址来寻址,这样做的好处是可以把全世界切割成无数小的子网。你发往“大洋彼岸”的数据,只需要知道下一跳路由器在哪,完全不需要知道对方具体的 MAC 地址。

第三点,路由器直接可以通过路由协议(OSPF、BGP等),可以像导航地图一样实时计算最佳路径。当某条海缆断了,路由器能动态绕行,这是交换机二层网络永远做不到的。

为什么某个交换机节点故障了会导致大面积的断网,但路由器不会

使用纯交换机组成树形结构的网络像是这样的:

            ┌─────────────┐
            │  核心交换机  │  ⬅️ 这台坏了 👇
            └──┬──┬──┬──┘
        ┌─────┘  │  └─────┐
   ┌────┴────┐   │  ┌────┴────┐
   │ 交换机A │   │  │ 交换机B │
   └──┬──┬──┘   │  └──┬──┬──┘
     PC1 PC2    PC3   PC4 PC5

核心交换机一旦宕机,所有的 PC 全部无法通信,整个网络完全瘫痪。即便交换机A、B都完好,它们也失去了与上层连接的通路,没有任何备用路径(因为树形结构没有环路,或者即便有环路也会被 STP 阻塞成无环树)。

但如果使用路由器把网络切成小块的话是这样的:

  网络1 (小)           网络2 (小)            网络3 (小)
  ┌─────────┐         ┌─────────┐          ┌─────────┐
  │ PC1 PC2 │         │ PC3 PC4 │          │ PC5 PC6 │
  └────┬────┘         └────┬────┘          └────┬────┘
       │                   │                    │
  ┌────┴────┐         ┌────┴────┐          ┌────┴────┐
  │ 路由器1  │◄───────►│ 路由器2  │◄────────►│ 路由器3  │
  └─────────┘         └────┬────┘          └─────────┘
                           ⬆️ 这台路由器2 挂了

网络2 内部:PC3 和 PC4 之间仍然可以互相通信(它们连在同一个交换机或路由器内网口,属于同一广播域,不依赖路由器2)。

网络2 访问外部:网络2 里的设备无法再访问网络1、网络3 以及互联网。

网络1 和网络3:它们之间的通信完全不受影响,可以继续正常互访。

结论:路由器2 的故障只让它负责的“网络2”对外断网,影响范围被牢牢限制在一个小区域内,没有扩散到其他网络。

而且路由器还支持冗余协议(如 VRRP/HSRP)和动态路由,所以可以这样设计:

        网络1                网络2 (关键网络)
       ┌──────┐            ┌──────┐
       │ R1   │            │ 虚拟网关 │  (VIP: 192.168.2.1)
       └──┬───┘            └──┬───┬──┘
          │                   │   │
          │      ┌────────────┘   └────────────┐
          │      │                             │
       ┌──┴──────┴──┐                     ┌────┴─────┐
       │   骨干网络   │                     │          │
       └──┬──────┬──┘                  ┌──┴──┐   ┌──┴──┐
          │      │                     │ R2a │   │ R2b │  (真实路由器)
          │      │                     └──┬──┘   └──┬──┘
          │      └──────────────┬────────┘         │
          │                     │                  │
          │                  ┌──┴──────────────────┴──┐
          │                  │   交换机 (网络2内部)    │
          │                  └─────┬──────┬──────────┘
          │                        │      │
          └─────(其他网络)─────   PC3    PC4

R2a 和 R2b 是一对冗余路由器,共同对外虚拟出一个“虚拟网关”(VIP)。

正常情况下,R2a 负责转发,R2b 处于备份状态。

一旦 R2a 宕机,R2b 会立刻接管虚拟网关,网络2 的内部设备对外通信几乎不受影响(仅丢失极少量正在传输的包)。

对于网络1 和更远的网络,动态路由协议会立刻发现 R2a 失效,将流量自动绕行到 R2b,整个互联网不会因为这一台路由器故障而瘫痪。

这时候就有人要问了,为什么交换机不能使用冗余设计来消灭单点故障

这是因为交换机中MAC地址表大小是有限的,当交换机的地址表中没找到对应的MAC地址的时候,就会进行全网广播,然而当形成环路的时候,广播操作就会一直在交换机之间发生,然后无限死循环,造成全网瘫痪。所以,为了避免这种情况的发生,二层网络物理上不能有环路。

所以我们回到前面,我们就可以用路由器来将一个个小网络连接起来

png6

下一步是将我们网络中的消息发送至目标网络。为此,我们将通过互联网服务提供商(ISP)连接至互联网。ISP 是管理特殊路由器的公司,这些路由器相互连接,并能访问其他 ISP 的路由器。因此,来自我们网络的消息将通过 ISP 网络的网络传输至目标网络。整个互联网正是由这样的网络基础设施构成的。

png7

ARP:通过 IP 找到 MAC 地址

即使知道要把数据交给默认网关,主机还需要知道网关的 MAC 地址。

因为在局域网里,数据链路层真正转发的是 MAC 帧。

主机会发送 ARP 请求:

谁是 192.168.1.1?请告诉 192.168.1.100

路由器回复:

192.168.1.1 的 MAC 地址是 aa:bb:cc:dd:ee:ff

之后,本机会把数据封装成以太网帧,发给网关的 MAC 地址。

这里要注意一个重要点:

IP 地址用于跨网络寻址,MAC 地址用于同一个局域网内的下一跳转发。

这一阶段主要对应:

网络层次协议 / 概念
数据链路层ARP、MAC、以太网帧

TCP 三次握手:建立可靠连接

在大多数情况下,一个HTTP请求会对应一个TCP连接。HTTP是基于TCP协议的,它使用TCP来传输HTTP请求和响应数据。

HTTP 1.0 和HTTP 2.0都基于TCP,而HTTP 3.0基于UDP

TCP 三次握手过程如下:

客户端 -> 服务器:SYN
服务器 -> 客户端:SYN + ACK
客户端 -> 服务器:ACK

三次握手的目的:

  1. 确认双方都能发送和接收数据
  2. 协商初始序列号
  3. 建立可靠传输连接

TCP 提供的能力包括:

能力说明
可靠传输丢包后可以重传
有序传输接收方按顺序交付数据
流量控制防止发送方把接收方打爆
拥塞控制避免把网络链路打爆
端口复用用端口区分不同应用进程

这一阶段主要对应:

网络层次协议
传输层TCP

TLS 握手:HTTPS 为什么安全

如果 URL 是 https://,TCP 连接建立后,还不能直接发送 HTTP 明文请求。

浏览器和服务器还要进行 TLS 握手。

TLS 握手主要做几件事:

  1. 协商 TLS 版本
  2. 协商加密套件
  3. 服务器发送证书
  4. 浏览器验证证书是否可信
  5. 双方协商出会话密钥
  6. 后续 HTTP 数据使用会话密钥加密传输

证书验证主要是为了确认:

我访问的真的是 www.example.com,而不是中间人伪造的网站。

TLS 解决的问题包括:

问题TLS 的作用
窃听加密传输内容
篡改校验数据完整性
冒充通过证书验证服务器身份

TLS 通常被认为位于应用层和传输层之间,也可以理解为 HTTPS 的安全基础。

关于TCP和TLS我以前的TLS Poison 攻击学习中都有提到过

数据是如何被一层层封装的

浏览器生成 HTTP 请求后,数据不会直接裸奔到网络上。

它会被一层层封装:

HTTP 数据
  ↓ 加 TCP 头
TCP Segment
  ↓ 加 IP 头
IP Packet
  ↓ 加 Ethernet 头和尾
Ethernet Frame
  ↓ 转成电信号 / 光信号 / 无线电波
物理介质上传输

接收方则反过来一层层拆包:

Ethernet Frame
  ↓ 去掉以太网头尾
IP Packet
  ↓ 去掉 IP 头
TCP Segment
  ↓ 去掉 TCP 头
HTTP 数据

每一层只关心自己的职责:

层次关注点
应用层传什么业务数据
传输层进程到进程,可靠性,端口
网络层主机到主机,IP 和路由
数据链路层相邻节点之间,MAC 和帧
物理层比特如何在介质上传输

路由器在中间做了什么

数据包从你的电脑到服务器,通常会经过多个路由器。

每个路由器主要做这些事:

  1. 收到数据帧
  2. 拆掉当前链路层头部
  3. 查看 IP 包的目标地址
  4. 查询路由表
  5. 找到下一跳
  6. 重新封装新的链路层帧
  7. 转发出去

一个很重要的点:

源 IP 和目标 IP 通常在传输过程中不变,但每一跳的源 MAC 和目标 MAC 都会变化。

例如:

电脑 -> 家用路由器
源 MAC:电脑 MAC
目标 MAC:路由器 MAC

路由器 -> 下一跳运营商设备
源 MAC:路由器出口 MAC
目标 MAC:下一跳设备 MAC

IP 负责端到端,MAC 负责下一跳。

服务器处理请求

服务器收到 HTTP 请求后,可能经历:

Nginx / Apache / Caddy
反向代理
后端应用服务
缓存 / 数据库
生成响应

例如访问一个动态页面时,后端可能会:

  1. 解析请求路径和参数
  2. 校验 Cookie 或 Token
  3. 查询 Redis 缓存
  4. 查询 MySQL / PostgreSQL
  5. 渲染 HTML 或返回 JSON
  6. 交给 Web 服务器返回给浏览器

如果是静态资源,比如图片、CSS、JS,服务器可能直接从磁盘或 CDN 返回。

浏览器解析并渲染页面

浏览器收到 HTML 后,会开始渲染页面。

大致流程:

  1. 解析 HTML,构建 DOM 树
  2. 解析 CSS,构建 CSSOM 树
  3. 合并 DOM 和 CSSOM,生成渲染树
  4. Layout,计算元素位置和大小
  5. Paint,绘制像素
  6. Composite,合成图层并显示

如果 HTML 中引用了 CSS、JS、图片、字体等资源:

<link rel="stylesheet" href="/style.css">
<script src="/main.js"></script>
<img src="/logo.png">

浏览器还会继续发起新的网络请求。

这些请求可能会:

  • 复用已有 TCP/TLS 连接
  • 使用缓存
  • 重新 DNS 查询
  • 走 CDN
  • 使用 HTTP/2 多路复用
  • 使用 HTTP/3 over QUIC

用这个过程串起网络分层

现在回头看,输入网址这件事正好把网络分层串起来了。

网络层次在这个过程中的体现
应用层DNS、HTTP、HTTPS
传输层TCP、UDP、端口、可靠传输
网络层IP、路由、跨网段转发
数据链路层MAC、ARP、以太网帧
物理层网线、光纤、Wi-Fi 信号

如果用 OSI 七层模型表示:

OSI 七层对应例子
应用层HTTP、DNS
表示层TLS、编码、压缩
会话层会话状态、连接管理
传输层TCP、UDP
网络层IP、路由
数据链路层Ethernet、MAC、ARP
物理层电信号、光信号、无线电波

总流程图

输入 URL
浏览器解析 URL
DNS 查询域名对应 IP
判断目标是否在同一网段
ARP 获取下一跳 MAC 地址
TCP 三次握手
TLS 握手
发送 HTTP 请求
服务器处理请求
返回 HTTP 响应
数据逐层拆包
浏览器解析并渲染页面

总结

输入网址并按下回车,看起来只是一个简单动作,但背后串起了计算机网络的大部分核心知识。

DNS 负责把域名变成 IP,IP 和路由负责把数据送到目标网络,ARP 和 MAC 负责局域网内的下一跳转发,TCP 负责可靠连接,TLS 负责安全加密,HTTP 负责应用层语义,浏览器最终负责解析和渲染页面。

如果把这些知识孤立地背,很容易混乱;但如果沿着“一次网页访问”的路径去看,每一层为什么存在、解决什么问题,就会清楚很多。

参考

互联网是如何工作的?

Licensed under CC BY-NC-SA 4.0
Build by Oight
使用 Hugo 构建
主题 StackJimmy 设计