服务器收取网络包完整流程

直接上流程:

网卡 → DMA → RX队列 → 硬中断 → 软中断 → 协议栈 → Socket队列 → 唤醒进程 → 系统调用 → 拷贝到用户态 → 应用处理

1. 物理层 & 网卡硬件接收

  1. 网线 / 光纤传来电信号 / 光信号
  2. 网卡(NIC)将信号解码成以太网帧
  3. 网卡校验帧格式、CRC 校验
  4. 校验通过后,通过 DMA 把帧写入主机内存的环形缓冲区(RX Queue)
    • 不会逐字节交给 CPU,直接内存写入,效率更高

2. 网卡触发硬件中断

  • 网卡写入完成后,向 CPU 发送硬件中断(IRQ)
  • 告诉 CPU:"有包到了,快来处理"

现代网卡支持 RSS(多队列),可以把不同流哈希到不同队列,绑定不同 CPU,避免单核瓶颈。

3. 内核硬中断处理(非常快)

内核中断处理程序做极简工作:

  1. 应答中断,让网卡继续收包
  2. 不做复杂协议处理
  3. 唤醒软中断(ksoftirqd) 去真正处理数据包
  4. 立即退出硬中断

目的:硬中断必须快,否则会阻塞其他硬件。

4. 内核软中断处理(真正收包逻辑)

内核线程 ksoftirqd 开始干活:

  1. 从内存 RX 队列取出以太网帧
  2. 剥离以太网头,判断是 IPv4/IPv6/ARP
  3. 交给 网络协议栈(netif_receive_skb)

5. 内核网络协议栈处理

① 网络层(IP 层)

  1. 解析 IP 头,校验
  2. 查路由表:判断是本机接收还是转发
  3. 如果是本机,根据协议字段交给:
    • TCP → TCP 协议栈
    • UDP → UDP 协议栈
    • ICMP → ICMP 处理

② 传输层(TCP/UDP)

UDP 流程
  1. 校验 UDP 头
  2. 根据 目的端口 查找对应 socket
  3. 把数据放入 socket 的 接收队列(recv_queue)
TCP 流程更复杂
  1. 处理序列号、滑动窗口
  2. 做 ACK 回复、重传管理、拥塞控制
  3. 按流重组,保证有序
  4. 数据放入对应 socket 的接收队列

到此为止,所有工作都在内核态完成。

6. 唤醒等待的用户进程

  • 当 socket 队列有数据时,内核会:
    1. 唤醒阻塞在 recv()/read()/epoll 上的应用进程
    2. 把进程从睡眠态 变为就绪态,等待调度

7. 进程被调度,进入系统调用

应用进程被 CPU 调度后,执行:

  • read()
  • recv()
  • recvfrom()

这些都是系统调用 ,会从用户态 → 内核态

8. 内核把数据拷贝到用户态缓冲区

  1. 内核从 socket 接收队列取出数据
  2. 将数据从 内核空间内存 → 拷贝到用户空间内存
  3. 拷贝完成,系统调用返回

这一步是传统网络最大开销之一:一次内存拷贝(用户态 / 内核态切换 + 数据复制)

9. 应用进程拿到数据,回到用户态执行

  • 应用开始处理 HTTP/DNS/ 业务协议等
  • 流程结束
相关推荐
我在人间贩卖青春1 个月前
汇编之软中断指令和协处理指令
汇编·arm·软中断·协处理
Qinti_mm2 个月前
Linux高性能UDP发包:硬中断、软中断与环形缓冲区揭秘
环形缓冲区·软中断·网络发包·硬中断
不穿格子的程序员4 个月前
操作系统篇3——深入理解操作系统:Linux 常用命令、系统中断与用户态/内核态详解
linux·服务器·操作系统·内核态·用户态·中断
赖small强4 个月前
Linux 系统调用在 ARM 上的实现与工作机制
linux·系统调用·内核态·用户态·上下文切换
赖small强5 个月前
Linux 用户态与内核态及其切换机制
linux·内核态·用户态(user mode)·硬件中断与异常·调度与抢占
egoist20235 个月前
[linux仓库]信号处理[进程信号·伍]
linux·信号处理·写时拷贝·软中断·硬件中断·缺页中断·时钟中断
韩曙亮1 年前
【系统架构设计师】操作系统 - 特殊操作系统 ③ ( 微内核操作系统 | 单体内核 操作系统 | 内核态 | 用户态 | 单体内核 与 微内核 对比 )
系统架构·操作系统·软考·内核态·用户态·微内核·微内核操作系统
zhoupenghui1682 年前
Golang协程详解
开发语言·后端·golang·用户态·gmp·调度器·内核线程态