网络:输入网址并回车之后的事

发布时间 2023-06-22 00:01:09作者: Jaywee

孤单小弟:HTTP

解析 URL

统一资源定位符:URL (Uniform Resource Locater)

标识互联网中资源的位置(包含协议、服务器、资源路径等信息)。

URL 解析

如果省略资源路径名,则访问默认文件。

通常是 index.html 或 default.html

生成 HTTP 请求信息

解析 URL 之后,浏览器确定了 Web 服务器和文件名。

从而生成 HTTP 请求报文。

报文格式:

HTTP 的消息格式

解析 URL 并生成 HTTP 请求信息后,需要委托操作系统发送消息。

发送之前,需要获取服务器域名对应的 IP 地址。

真实地址查询:DNS

域名服务器:DNS (Domain Name System)

保存服务器域名与 IP 地址的映射关系。

域名层级关系

  • 域名层级通过 . 划分,越靠右的层级越高(e.g. www.server.com)

  • 域名最后还有一个 .(通常省略),代表根域名(e.g. www.server.com.)

  • 结构:

    • 根域名服务器(.)

    • 顶级域名服务器(.com)

    • 权威/权限域名服务器(server.com)

    • 本地域名服务器

      DNS 树状结构

域名解析流程

假设要解析的目标域名:www.server.com(下称目标域名)

  1. 客户端:向本地 DNS 发起请求,询问目标域名的 IP 地址。

  2. 本地 DNS:

    1. 收到客户端请求。
    2. 查缓存:如果缓存里的表格能找到目标域名,则直接返回 IP 地址。否则进行下一步。
    3. 请求根域名服务器:向根 DNS 发出请求,询问目标域名的 IP 地址。
  3. 根 DNS:

    1. 收到本地 DNS 请求。
    2. 发现后缀是 .com,说明目标域名归 .com 区域管理。
    3. 响应:将目标域名的顶级 DNS(.com)的 IP 地址响应给本地 DNS。
  4. 本地 DNS:

    1. 收到根 DNS 的响应。
    2. 向 .com 顶级 DNS 发起请求,询问目标域名的 IP 地址。
  5. 顶级 DNS:

    1. 收到本地 DNS 请求。
    2. 发现后缀是 server.com,说明目标域名归 server.com 区域管理。
    3. 响应:将目标域名的权威 DNS(server.com)的 IP 地址响应给本地 DNS。
  6. 本地 DNS:

    1. 收到顶级 DNS 的响应。
    2. 向 server.com 权威 DNS 发起请求,询问目标域名的 IP 地址。
  7. 权威 DNS:

    1. 收到本地 DNS 请求。
    2. 服务器查询目标域名对应的IP 地址,响应给本地 DNS。
  8. 本地 DNS:

    1. 收到权威 DNS 响应。
    2. 将 IP 地址返回客户端。
  9. 客户端:和目标建立连接。

    域名解析的工作流程

缓存

缓存可以提高域名解析效率

  • 浏览器、操作系统、DNS 服务器等都会保存域名解析结果。
  • 各个环节都会检查自身有没有域名的缓存,有则直接返回,没有才进行下一步。
    1. 浏览器缓存
    2. 操作系统缓存
    3. hosts 文件
    4. 本地 DNS 缓存

指南好帮手:协议栈

  • 应用程序:浏览器调用 Socket 库,委托协议栈工作。

  • 协议栈:分为两部分,收到委托后执行工作。

    • TCP 和 UDP 协议:接收应用层的委托,执行收发数据的操作。
    • IP 协议:控制网络包收发操作。
      • 在互联网上传数据时,数据会被切分成一块块的网络包,由 IP 负责发送给对方。
      • IP 还包括 ICMP 协议和 ARP 协议。
        • ICMP:用于告知网络包传送过程中产生的错误以及各种控制信息。
        • ARP:根据 IP 地址查询相应的以太网 MAC 地址。
  • 驱动程序:网卡驱动程序负责控制网卡硬件。

  • 硬件:物理硬件网卡负责完成实际的收发操作(对网线中的信号执行发送和接收操作)。

    img

可靠传输:TCP

HTTP 基于 TCP 协议传输

首部

  1. 源端口号、目标端口号:

    • 浏览器监听端口:通常随机生成。
    • 服务器监听端口:HTTP 默认 80, HTTPS 默认 443。
  2. 序号:解决包乱序的问题。

  3. 确认号:解决丢包的问题。

    • 确认发出去对方是否有收到。
    • 没有收到就应该重新发送,直到送达。
  4. 状态位:维护连接状态

    • SYN:发起连接
    • ACK:回复
    • RST:重新连接
    • FIN:结束连接
  5. 窗口大小:

    • 流量控制:通信双方各声明一个窗口(缓存大小)代表自身当前的处理能力,避免传输的太快或太慢。

    • 除了流量控制,TCP 还有拥塞控制。

      TCP 包头格式

建立连接:三握

HTTP 传输数据之前,需要建立 TCP 连接(aka. 三次握手)。

  • 连接:双方计算机里维护一个状态机,是虚拟的连接。
  • 三次握手:目的是保证双方都有发送和接收的能力。

客户端和服务端都处于 CLOSED 状态。服务端先主动监听某个端口,处于 LISTEN 状态。

  1. 客户端:

    • 主动发起连接 SYN
    • 之后处于 SYN-SENT 状态
  2. 服务端:

    • 收到客户端 SYN
    • 返回 SYN、对客户端的 SYN 确认 ACK
    • 之后处于 SYN-RCVD 状态
  3. 客户端:

    • 收到服务端 SYN 和 ACK
    • 对服务端 SYN 确认 ACK
    • 之后处于 ESTABLISHED 状态(因为一发一收成功)
  4. 服务端:

    • 收到客户端的 ACK
    • 之后处于 ESTABLISHED 状态(因为一发一收成功)

    TCP 三次握手

查看 TCP 连接状态:Linux 的 netstat -napt 命令。

TCP 连接状态查看

TCP 分割数据

  1. 场景:HTTP 请求消息超过了 MSS 的长度,TCP 需要把数据拆分后发送,而不是一次性发送所有数据。

    • MTU(最大传输单元):一个网络包的最大长度,以太网中一般为 1500 字节。

    • MSS(最大报文段长度):除去 IP 和 TCP 头部之后,一个网络包所能容纳的 TCP 数据的最大长度。

      MTU 与 MSS

  2. 拆分流程:

    • 以 MSS 为单位来拆分数据,拆分出来的每一块数据会放进单独的网络包。

    • i.e. 每个被拆分数据加上 TCP 首部信息,分别交给 IP 模块来发送数据。

      数据包分割

TCP 报文生成

此时网络包如下图所示:

  • TCP 报文 = TCP 首部 + TCP 数据
  • TCP 数据 = HTTP 首部 + 数据

TCP 层报文

远程定位:IP

TCP 模块在执行连接、收发、断开等各阶段操作时,

需要委托 IP 模块,将数据封装成网络包发送给通信对象。

首部

  • 协议:HTTP 基于 TCP 传输,则协议号为 06(十六进制)代表使用 TCP 协议。

  • 源 IP 地址:客户端输出的 IP 地址。

  • 目标 IP 地址:通过 DNS 域名解析得到的服务器 IP 地址。

    IP 包头格式

路由表

场景:客户端有多个网卡,存在多个 IP 地址。

需要根据路由表规则,判断哪个网卡作为源 IP 地址。

  • 判断机制:

    • 接收方 IP 地址和子网掩码(Genmask)进行与运算,结果与目标地址(Destination)相同的作为源 IP 地址。
    • 对路由表的记录逐条判断,直到确定源 IP 地址。
  • 查看当前系统的路由表:Linux 系统 route -n 命令。

    路由表

  • 默认网关:假如路由表中前面所有记录都不匹配,会使用最后一行的默认网关。。

    • 目标地址和子网掩码:都是 0.0.0.0
    • 网关:路由器的 IP 地址

示例:服务器的目标地址是 192.168.10.200,客户端的路由表如上

  1. 匹配过程:

    • 第一条:与运算结果 192.168.10.0,与 Destination 不相等,匹配失败。
    • 第二条:与运算结果 192.168.10.0,与 Destination 相等,匹配成功。
  2. 确定源 IP 地址:网卡 eth1 的地址。

    路由规则判断

IP 报文生成

此时网络包如下图所示:

  • IP 报文 = IP 首部 + IP 数据
  • IP 数据 = TCP 报文 = TCP 首部 + TCP 数据
  • TCP 数据 = HTTP 首部 + 数据

IP 层报文

两点传输:MAC

首部

MAC 首部是以太网使用,MAC 地址用于两点之间的传输。

  • 发送方 MAC 地址(源):在网卡生产时写入到 ROM,可以直接读取。

  • 接收方 MAC 地址(目标):下一跳的 MAC 地址,可能是路由器也可能是目标服务器。

    1. 在路由表中找到相匹配的条目,Gateway 列值就是接收方的 IP 地址。
    2. 通过 ARP 协议,获取 MAC 地址。
  • 协议类型:在 TCP/IP 通信中,通常只有两种取值。

    • 0800 : IP 协议

    • 0806 : ARP 协议

      MAC 包头格式

ARP

广播

机制

  • ARP 协议在以太网中通过广播的形式,向所有设备询问 IP 地址对应的 MAC 地址。

  • 其它设备收到 ARP 的广播后,检查 IP 地址是否一致,是则返回 MAC 地址。

    ARP 广播

缓存

操作系统会将 ARP 查询结果放到内存空间中(ARP 缓存),缓存几分钟。

  1. 查看 ARP 缓存内容:Linux 系统的 arp -a 命令。

    ARP 缓存内容

  2. 完整 ARP 发包过程:

    1. 缓存:查询 ARP 缓存,如果其中已经保存了对方的 MAC 地址,就不需要发送 ARP 查询,直接使用 ARP 缓存中的地址。
    2. 广播:当 ARP 缓存中不存在对方 MAC 地址时,则发送 ARP 广播查询。

MAC 报文生成

此时网络包如下图所示:

  • MAC 报文 = MAC 首部 + MAC 数据
  • MAC 数据 = IP 报文 = IP 首部 + IP 数据
  • IP 数据 = TCP 首部 + TCP 数据
  • TCP 数据 = HTTP 首部 + 数据

MAC 层报文

出口:网卡

网络包是内存中的一串二进制数字信息,需要将转换为电信号才能在网线上传输。

负责执行这一操作的是网卡,要控制网卡还需要靠网卡驱动程序。

网卡驱动工作流程:获取网络包之后,将其复制到网卡内的缓存区,在其头尾添加内容。

  • 头部:添加报头和起始帧分界符(标记包的起始位置)。

  • 尾部:添加帧校验序列(FSC, Frame Check Sequence),用于检查包传输过程是否有损坏。

    数据包

送别者: 交换机

  • 交换机工作在 MAC 层,也称为二层网络设备。
  • 交换机的设计是将网络包原样转发到目的地。

接收包

接收过程

  1. 电信号到达网线接口,交换机里的模块进行接收并将电信号转换为数字信号。
  2. 通过包末尾的 FCS 校验错误,如果没问题则放到缓冲区。
  3. 查询 MAC 地址表:判断地址表中是否有包的接收方 MAC 地址。
    • 是:将数字信号发送到对应端口。
    • 否:将包转发到除了源端口之外的所有端口上(当接收方地址是广播地址 FF:FF:FF:FF:FF:FF,也进行该操作)。

Hint 1:网卡 vs 交换机

计算机的网卡具有 MAC 地址,交换机的端口没有。

对于收到的网络包,处理如下。

  • 计算机网卡:核对接收方 MAC 地址,判断不是发给自己的则丢弃。
  • 交换机端口:不核对接收方 MAC 地址,直接接收所有的包并存放到缓冲区。

Hint 2:MAC 地址表信息

包含信息

  • 连接到交换机的设备 MAC 地址

  • 设备连接在交换机的哪个端口

    交换机的 MAC 地址表

出境大门:路由器

路由器 vs 交换机

网络包经过交换机之后,

到达路由器,在此被转发到下一个路由器或目标设备。

路由器 交换机
设计基础 基于 IP 基于以太网
aka. 三层网络设备
(网络、数据链路、物理)
二层网络设备
(数据链路、物理)
端口情况 具有 MAC 地址和 IP 地址 不具有 MAC 地址

路由器基本原理

功能

  • 具有 MAC 地址,可以作为以太网的发送方和接收方;
  • 具有 IP 地址,此处的功能和计算机的网卡相同。

转发操作:当转发包时

  1. 接收包:路由器端口会接收发给自己的以太网包。
  2. 查表:查询路由表,确认转发目标。
  3. 转发:由相应的端口作为发送方,将以太网包发送出去。

接收包

  1. 电信号到达网线接口,路由器中的模块进行接收并将电信号转成数字信号。
  2. 通过包末尾的 FCS 校验错误,没问题则继续。
  3. 比较 MAC 首部的接收方 MAC 地址:对比自身 MAC 地址。
    • 相同则放到接收缓冲区。
    • 否则丢弃包。

查询路由表

判断机制:同上文 IP 的路由表

  • 接收方 IP 地址和子网掩码(Genmask)进行与运算,结果与目标地址(Destination)相同的作为源 IP 地址。

  • 默认网关:假如路由表中前面所有记录都不匹配,会使用最后一行的默认网关。

    路由器转发

上图中的第二条记录会匹配,即目标地址 192.168.1.0

转发

生成 MAC 报文

  • 接收方 MAC 地址:
    1. 确认接收方 IP 地址:查看路由表的 Gateway 列值。
      • IP 地址:说明包尚未抵达终点,将包转发到该 IP 地址。
      • 空:说明已抵达终点,将包转发到 IP 首部的接收方 IP 地址。
    2. ARP 协议:查询 IP 地址对应的 MAC 地址。
      • 查缓存,有则返回。
      • 发送 ARP 查询请求。
  • 发送方 MAC 地址:填写输出端口的 MAC 地址。
  • 协议字段:填写 0800 (十六进制)表示 IP 协议。

发出 MAC 报文

  1. 路由器将网络包发出,通过交换机到达下一个路由器。
  2. 重复以上步骤,经过层层转发到达目的地。

在网络包传输的过程中,

IP 地址始终不变,MAC 地址随着设备改变而改变。

扒皮:服务器 & 客户端

数据包抵达服务器后,服务器开始扒皮

  1. 检查 MAC 首部:比较自身的 MAC 地址,相同则继续。
  2. 检查 IP 首部:
    1. 比较自身的 IP 地址,相同则继续。
    2. 检查 IP 首部的协议项,知道传输层是 TCP 协议。
  3. 检查 TCP 首部:
    1. 序列号:确认序列包是不是想要的。是则放入缓存后返回 ACK,不是则丢弃。
    2. 端口号:HTTP 服务器正在监听这个端口号。
  4. 将包发送给相应的 HTTP 进程。
  5. HTTP 进程:收到 HTTP 请求,将请求想要的资源封装在 HTTP 响应报文。

后续

  1. 服务端:将 HTTP 响应报文发送给客户端(类似请求报文的过程,区别是源地址和目的地址互换)
  2. 客户端:类似服务端对 HTTP 请求报文的处理,扒皮,获得响应数据包。
  3. 断开 TCP 连接(aka. 四次挥手)

网络分层模型