外观
程序怎样把数据交给网卡?
阶段 0 · 计算机与数据基础 · 第 2 课
你在电脑上同时打开了聊天软件和浏览器。当你在聊天框按下发送键,想把字母 A 发出去时,为什么聊天软件不能自己直接往网卡上写电信号?如果两个软件同时抢网卡,数据会不会撞成一团?
在第 1 课中,我们知道字母 A 在计算机里编码为一个字节(Byte) 01000001。这一课我们留在发送端主机内部,追踪这个字节如何从应用程序一路走到网卡硬件。
学完本课后,你将能够:
- 解释程序、进程、操作系统与驱动程序在发送数据时的分工。
- 定位一个待发送字节在用户空间内存、内核缓冲区和网卡硬件之间的搬运路径。
- 说出直接内存访问(DMA)与中断为什么能把 中央处理器(CPU) 从繁重的数据搬运中解放出来。
1. 先看图:三个区域各管什么?
上图把一台电脑的发送路径分成了三个区域:
- ① 用户空间(应用程序):你运行的聊天软件、浏览器都在这里工作。它们只负责生成或展示业务数据(例如把字母
A变成01000001),不能直接碰触硬件。 - ② 内核空间(操作系统与驱动):操作系统的核心区域。它替所有软件统一排队、按网络规则加上控制头,再通过网卡驱动程序指挥网卡。
- ③ 硬件设备(网卡 NIC):真正的物理接口,负责把内存里的字节流变成网线上的电信号或光纤里的光脉冲。
2. 程序与进程:为什么软件之间不会串门?
躺在硬盘里的聊天软件可执行文件只是静态的代码,叫作程序(Program)。当你双击启动它,操作系统就会在内存(RAM)里为它分配一块独立的区域,并让 中央处理器(CPU) 执行它的指令——这个正在运行的程序实例就是进程。
为什么聊天软件不会读到或改掉浏览器里的网页密码?因为操作系统实施了内存隔离:
- 每个进程都以为自己独占了一片连续的内存(虚拟内存),聊天软件把
01000001放在自己的用户态内存里。 - 进程运行在受限的用户态(User Mode),没有权限直接读写其他进程的内存,也没有权限直接向网卡寄存器下达硬件指令。
- 当聊天进程想要联网发送
01000001时,必须向操作系统发起一次系统调用(例如调用发送接口send或write),请求内核代为发送。
3. 跟着数据走:从用户内存到网卡队列
我们先预测一下:如果聊天软件一秒钟产生 1000 条消息,而网卡由于链路繁忙暂时没发完,多出来的数据放在哪?答案是内存里的缓冲区。
让我们跟着 01000001 走完主机内部的四步交接:
| 步骤 | 当前数据是什么 | 存放在哪里 | 谁在操作 | 依据什么决定下一步 |
|---|---|---|---|---|
| ① 准备应用数据 | 1 字节应用数据 01000001 | 聊天进程的用户空间内存 | 聊天进程(CPU 用户态) | 用户点击“发送”,发起系统调用 |
| ② 拷入内核并封装 | 附加上各层协议控制头的数据包 | 操作系统内核发送缓冲区 | 操作系统内核网络栈(CPU 内核态) | 查找本机路由与接口,决定从哪张网卡发出 |
| ③ 挂载发送队列 | 完整的待发以太网帧字节序列 | 内存中的网卡发送环形队列(TX Ring) | 网卡驱动程序 | 填写描述符(内存地址与长度),通知网卡取数据 |
| ④ 硬件读取并发送 | 二进制比特流 → 物理信号 | 网卡内部缓存 → 物理网线 | 网卡(NIC)(DMA + MAC + PHY) | 按描述符地址读取内存,校验并编码上线 |
4. CPU、内存与网卡怎样高效配合?
如果每发一个字节,都要让 中央处理器(CPU) 亲自从内存(RAM)里读出来、再塞进网卡,那么在千兆(每秒约 1.25 亿字节)或万兆网络下,CPU 光搬运数据就会忙得不可开交。
现代计算机用 直接内存访问(DMA) + 中断 解决了这个问题:
- 驱动填单(描述符):CPU 执行网卡驱动程序代码,在内存队列里写下一张“提货单”(描述符),标明:“待发送的帧在内存地址
0x...,长度多少字节”,然后敲一下网卡的门铃寄存器。 - 网卡自己提货(DMA):网卡里的 直接内存访问(DMA) 引擎直接通过主板总线(如 PCIe)去内存读取这帧数据,交给 MAC 和 PHY 发送上网线。这期间 CPU 可以转身去处理别的程序。
- 干完活汇报(中断):网卡把一批帧发送完毕(或者从网线上收到了新帧并写入内存)后,向 CPU 发出一个硬件中断。CPU 收到通知后,再去清理已发送的缓冲区或把新收到的数据交给对应进程。
从模型到真实系统: 上述模型假设只有单队列中断。在真实的高负载 Linux 服务器上,为了防止每秒几十万次中断打断 CPU,网卡驱动还会启用 NAPI(轮询合并) 和 多队列 RSS,把一次中断变成批量收取多帧。
5. 小结与下一步
- 进程与隔离:运行中的程序是进程,它把
01000001放在自己的内存里,通过系统调用请求操作系统联网。 - 内核与驱动:操作系统在内核缓冲区中组织通信数据,通过驱动程序管理网卡收发队列。
- DMA 与中断:网卡利用 直接内存访问(DMA) 直接从内存(RAM)搬运数据,完成后用中断通知 中央处理器(CPU)。
现在,发送端已经能把一串字节顺利推上网线了。但如果两台电脑直接用一根网线连起来,接收端收到一长串 0 和 1 时,怎样知道哪几个字节是文件名、哪几个字节是文件内容?下一课我们来看为什么两台电脑交换数据必须设计协议。