1. 网络协议各层做了哪些事情?

75 阅读9分钟

在浏览器的某个支付页面发起一次完整的支付请求,网络协议的各个层级分别做了哪些事情?

1. 应用层

应用层简要理解做了哪些事情?

  1. 通过DNS协议或者HTTPDNS协议得到目标应用的ip地址。
  2. 通过HTTP协议或者HTTPS协议将业务应用请求封装出一个正常的http请求包。
  3. 浏览器将http请求包交给传输层处理(socket编程)。
image.png

2. 传输层

传输层简要理解做了哪些事情?

  1. 通过TCP协议UDP协议将http包封装出新的TCP包或者UDP包。
  2. TCP或者UDP协议在封装报文时写入源端口 + 目标端口。
  3. 浏览器将包交给操作系统的网络层
image.png

3. 网络层

网络层简要理解做了哪些事情?

  1. 通过IP协议将TCP包或者UDP包封装出对应的IP包。
  2. IP协议会在封装报文时写入源IP地址 + 目标IP地址。
image.png

4. 数据链路层

数据链路层简要理解做了哪些事情?

  1. 通过ARP协议拿到ip地址对应的网关地址(本地网关默认为:192.168.1.1)对应的mac地址(如 00:1A:2B:3C:4D:5E)。

  2. 将本机的mac地址 + 网关的mac地址封装到mac包中,发送给网关。 image.png

  3. 网关内部维护了一张路由表,可以识别到目标IP接下来应该前往哪个路由(路由协议OSPF、BGP)。

    image.png
  4. 最后一个路由内部识别到目标ip是自己的网段内的,再次通过ARP协议得到目标ip的mac地址,并通过此mac地址完成mac包的发送。

  5. 目标服务器收到mac包后,校验mac地址;通过后,取下mac头,交给网络层,校验IP;通过后,取下IP头,将TCP包或UDP包交给传输层,对每个收到的帧数据进行恢复确认;确认后,传输层通过端口号,将数据包交给对应的应用层进行数据解析处理。

6. 物理层

将Frame帧转换为比特流(电信号/光信号)进行传输。

5. 整体流程

image.png

Q&A

网络包的协议头在发送和接收时是怎么写入和剥离的?

发送时(内存 + 硬件)

  1. 内存缓冲区预留14 + 20 + 20个字节的位置给到mac头、tcp头、ip头。
  2. 内存缓存区中从55的位置开始向后填充数据,之后逐层向预留空间内写入头信息。
  3. 最后计算并准假FCS校验帧到缓冲区的尾部,此时一个完整的数据包就生成了。
帧0:分配        [                                                                ]
                ↑head/data/tail
                
帧1:预留        [54预留 |                                                         ]
                ↑head  ↑data/tail
                0x1000 0x1036
                
帧2:加数据      [54预留 |100数据|                                                  ]
                ↑head  ↑data  ↑tail
                0x100  0x1036 0x109A 
                
帧3:加TCP头     [34预留 |20TCP |100数据|                                           ]
                ↑head  ↑data          ↑tail
                0x100  0x1022         0x109A
                
帧4:加IP头      [14预留 |20IP |20TCP |100数据|                                     ]
                ↑head  ↑data              ↑tail
                0x100  0x100E             0x109A
                
帧5:加以太头    [14以太 |20IP |20TCP |100数据|                                      ]
               ↑head/data                  ↑tail
               0x100                       0x109A
                
帧6:网卡发送    [14以太 |20IP |20TCP |100数据|    +   4FCS(帧校验序列)              ]
               ↑head/data               ↑tail    
               --------↑sk_buff范围------        ↑FCS在sk_buff外(硬件网卡添加)
               
head = 0x1000

预留54字节后:
data = 0x1000 + 0x36 = 0x1036  (54=0x36)

添加100字节数据后:
tail = 0x1036 + 0x64 = 0x109A  (100=0x64)
len = 0x64 = 100

添加TCP头20字节:
data = 0x1036 - 0x14 = 0x1022  (20=0x14)
len = 100 + 20 = 120

添加IP头20字节:
data = 0x1022 - 0x14 = 0x100E
len = 120 + 20 = 140

添加以太网头14字节:
data = 0x100E - 0x0E = 0x1000  (14=0x0E) ← 回到head!
len = 140 + 14 = 154

接收时

帧0:网卡接收     [14以太|20IP|20TCP|100数据|4FCS]   ← 网卡完整接收
                
帧1:硬件校验     [14以太|20IP|20TCP|100数据|4FCS]   ← 校验CRC32
                校验通过✅
                
帧2:剥离FCS     [14以太 | 20IP| 20TCP| 100数据|    ]   ← 硬件移除FCS,放入sk_buff
                ↑head/data                   ↑tail
                0x1000                       0x109A
                
帧3:去以太头     [14以太 | 20IP| 20TCP| 100数据|    ]
                ↑head   ↑data                ↑tail
                0x1000  0x100E               0x109A
                
帧4:去IP头      [14以太 | 20IP |20TCP |100数据|    ]
                ↑head         ↑data         ↑tail
                0x1000        0x1022
                
帧5:去TCP头     [14以太 |20IP |20TCP | 100数据|    ]
                ↑head               ↑data   ↑tail
                0x1000              0x100E  0x109A
                
帧6:应用读取    [14以太 |20IP |20TCP |100数据|    ]
                ↑head              ↑data   ↑tail
                0x1000             0x1022  0x109A
                应用读取100字节数据

为什么各个协议头放到头部而不是尾部?

网络设备经常处理"流":
收到开头几个字节就能开始处理

头部在前:收到14字节就知道是不是发给我的
头部在后:必须收到整个包才知道

192.168.1.1是什么?

默认网关(路由器)

您的设备配置:
IP地址:    192.168.1.100  (您的电脑/手机)
子网掩码:  255.255.255.0  (/24)
默认网关:  192.168.1.1    (路由器)

所有非本地流量 → 发送到 192.168.1.1 → 路由器 → 互联网

私有地址范围

192.168.0.0 - 192.168.255.255  (192.168.0.0/16)
├─ 192.168.0.0/24   (192.168.0.1 - 192.168.0.254)
├─ 192.168.1.0/24   (192.168.1.1 - 192.168.1.254) ← 最常用!
├─ 192.168.2.0/24
└─ ... 共256个这样的网段

为什么要用私有地址?

公有IP稀缺且昂贵:
一个家庭只需1个公有IP(路由器WAN口)
内部所有设备用私有IP(免费、可重复使用)

您的家庭网络:       互联网看到的:
├─ 手机: 192.168.1.101     │
├─ 电脑: 192.168.1.102     ├─ 都显示为 123.123.123.123
├─ 平板: 192.168.1.103     │  (您的路由器公有IP,但是标注用户代理是手机还是电脑等)
└─ 路由器WAN: 123.123.123.123

典型的网络拓扑

互联网
    │
    ├─ 光猫/调制解调器
    │     │
    │     WAN口: 公有IP (如 123.123.123.123)
    │
    └─ 路由器 (192.168.1.1)
          │
          ├─ 电脑: 192.168.1.100
          ├─ 手机: 192.168.1.101  
          ├─ 电视: 192.168.1.102
          └─ ... 最多253个设备

子网划分

192.168.1.0/24 网段:
网络地址:  192.168.1.0    (标识整个网络)
可用主机:  192.168.1.1 - 192.168.1.254
广播地址:  192.168.1.255  (发给该网段所有设备)

通常分配:
192.168.1.1     路由器/网关
192.168.1.2-99  静态分配设备(服务器、NAS等)
192.168.1.100-254 DHCP动态分配(手机、电脑等)

HTTPDNS协议是什么?

传输层的端口

image.png

通信过程示例(以访问网页为例)

a. 服务器端:Nginx Web服务器启动,主动绑定到 0.0.0.0:80 并监听。

b. 客户端:您在浏览器输入网址,浏览器请求内核建立一个TCP连接。

c. 源端口分配:您的操作系统从临时端口池(如 49152-65535)中挑选一个未被使用的端口(例如 59234)分配给这个浏览器标签页。

d. 封装与发送:内核构建TCP报文,设置:

  • 源端口59234(客户端临时端口)
  • 目标端口80(服务器知名端口)

e. 服务器响应:服务器回包时,会将源端口和目标端口对调

  • 源端口80
  • 目标端口59234

这样,双方的协议栈就能根据  “协议, 源IP, 源端口, 目标IP, 目标端口”  唯一标识一个通信连接或数据流。

ip地址为什么不在网络层再解析?

既然ip协议是在网络层,为什么要在应用层就用DNS服务解析出ip地址呢?如果网络层直接处理域名翻译,会出现以下情况:

  • 每个数据包携带域名,头部臃肿
  • 所有路由器需要解析DNS,性能暴跌
  • DNS故障导致全网瘫痪
  • 路由表需存储全球域名,内存爆炸

而现有在应用层直接处理的优势是:

  • 应用层解析一次,缓存结果,多次使用
  • 网络层专注快速转发,毫秒级路由
  • 灵活性强:DNS记录可随时更新,网络层无感知
  • 安全性好:中间设备看不到通信语义

为什么不能仅仅依靠IP寻址,还要有mac地址呢?

MAC地址

  • 固化:由网卡制造商烧录,理论上全球唯一,且通常终身不变。
  • 扁平结构:没有内在的层次关系。AA-BB-CC-DD-EE-FF 和 11-22-33-44-55-66 之间看不出任何地理位置或网络归属的关联。
  • 不适合路由:互联网上有数十亿设备,路由器无法维护一个包含所有MAC地址的、没有结构的“世界通讯录”来寻路。

IP地址

  • 动态分配:由网络管理员或DHCP服务器分配,可以随时改变(比如你换个Wi-Fi,IP就变了)。
  • 层次化结构:像电话号码(国家码+区号+本地号)一样是分层的。例如 192.168.1.10192.168.1.0/24 表示一个子网。路由器只需要知道如何到达某个网络(比如 18.0.0.0/8 属于某公司),而不需要知道该网络内每一台具体设备。
  • 完美适合路由:路由器之间通过路由协议(如BGP)交换网络路径信息,构建出一张高效的“互联网地图”,指导数据包在复杂的网络环境中跳转。

“最后一公里”问题:IP地址在局域网内无法直接定位

这是最直接的技术原因。假设在一个局域网内,你的电脑(IP: 192.168.1.100)想给同一Wi-Fi下的打印机(IP: 192.168.1.200)发送数据。

  • 仅有IP地址时:你的电脑只知道打印机的“逻辑地址”(IP),但它无法直接在电波或网线上喊话:“IP是192.168.1.200的,请接收!” 因为网络硬件(网卡、交换机)只认MAC地址。它们是通过MAC地址来识别和转发数据的。
  • 解决方案的悖论:你可能会想:“那就让交换机也学会IP地址啊!” 这实际上就是把交换机升级成路由器了。但路由器工作在网络层,其复杂度、成本和时延都比交换机(数据链路层设备)高得多。用路由器来处理局域网内部海量的、高速的通信(如文件共享、视频流),是极其低效和不经济的。

交换机和路由器的区别

image.png