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

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

孤单小弟:HTTP

解析 URL

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

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

URL 解析

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

通常是 index.htmldefault.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 库,委托协议栈工作。

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

    • TCPUDP 协议:接收应用层的委托,执行收发数据的操作。
    • 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. 客户端

    • 收到服务端 SYNACK
    • 对服务端 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. 四次挥手)

网络分层模型