Linux 网络包的 “快递分拣”:从发送到接收的内核协作全景

简介: 本文以“快递分拣”为喻,详解Linux网络包从发送到接收的内核协作流程。通过系统调用、sk_buff封装、协议栈分层处理及硬/软中断协同,展现数据如何在应用层、内核与网卡间高效流转,揭示零拷贝、中断分工与分层设计等核心机制,呈现Linux网络栈精密高效的运作全景。(238字)

Linux 网络包的 “快递分拣”:从发送到接收的内核协作全景

日常在 Linux 系统里打开浏览器、传文件时,看似简单的 “发送 / 接收数据”,背后其实是内核中多个模块精密配合的 “流水线作业”。今天我们就跟着网络包的脚步,拆解它在 Linux 内核中从 “发起” 到 “抵达” 的完整旅程。

一、发送流程:从应用层到网卡的 “打包发货”

把网络包比作快递,那么 Linux 发送包的过程,就是给快递逐层 “打包”、并送到 “快递站(网卡)” 的过程。

1. 应用层:发起 “寄件请求”

当你在应用程序里调用send()write()(比如浏览器发送 HTTP 请求),其实是把数据 “交给” 内核 —— 这一步会触发系统调用,从用户态切换到内核态,数据进入内核的 socket 子系统。

2. Socket 层:快递的 “初始登记”

Socket 是应用层与内核网络栈的 “接口窗口”,它会把应用数据封装成sk_buff(套接字缓冲区)—— 这是内核中承载网络包的 “快递箱”,通过指针操作避免数据拷贝,高效管理包的生命周期。此时sk_buff里只有应用数据,接下来要进入协议栈逐层 “包装”。

3. 传输层:给快递贴 “运输标签”

以 TCP 为例(UDP 流程类似但无连接):

  • TCP 模块会给sk_buff添加TCP 头部:包含源端口、目的端口(确定应用程序)、序号(保证有序)、确认号(保证可靠)等信息,相当于给快递贴上 “运输单”。
  • 这里会用到之前预留的头部空间(通过sk_buffdata指针前移实现),不用拷贝数据,只动指针 —— 这是 Linux 网络栈高效的关键之一。

4. 网络层:规划 “运输路线”

IP 模块接手后,主要做两件事:

  • 选路由:通过路由表确定 “下一跳” 设备(比如网关),相当于查快递的 “中转路线”。
  • 加 IP 头部:给sk_buff添加源 IP、目的 IP、协议类型(标记是 TCP/UDP)等信息,相当于给快递贴 “地址标签”。

5. 链路层:包上 “同城配送面单”

到了链路层(比如以太网),需要确定 “下一跳设备的物理地址”:

  • 通过ARP 协议查询下一跳 IP 对应的 MAC 地址(如果缓存里没有,就广播询问)。
  • sk_buff添加以太网头部:包含源 MAC、目的 MAC、帧类型(标记是 IP 包),相当于给快递贴 “同城配送面单”。

6. 网卡:快递 “出站”

最后,sk_buff被交给网卡驱动:

  • 驱动把sk_buff里的二进制数据转为电信号 / 光信号。
  • 通过网卡硬件发送到物理网络中 —— 这时候网络包才算真正 “离开” Linux 系统。

二、接收流程:从网卡到应用层的 “拆包收货”

接收流程是发送的逆过程,但因为要处理 “突发的网络数据”,Linux 用了 “硬中断 + 软中断” 的分工来保证效率。

1. 网卡:触发 “快递到站通知”

当网卡收到网络包后,会触发硬中断(硬件层面的信号),告诉内核 “有新包来了”。硬中断的处理非常 “快”:只把包从网卡的环形缓冲区拷贝到内核的sk_buff,然后标记 “待处理”,立刻结束 —— 避免长时间占用 CPU,影响其他任务。

2. 软中断:“精细分拣快递”

硬中断结束后,会触发软中断(内核线程ksoftirqd负责处理),这才是接收流程的核心:软中断从 “待处理队列” 中取出sk_buff,开始逐层 “拆包”。

3. 链路层:拆 “同城面单”

链路层先解析以太网头部:

  • 检查 MAC 地址是否是本机(或广播地址),如果不是就丢弃。
  • 去掉以太网头部,把剩下的内容交给网络层。

4. 网络层 + 传输层:逐层拆 “地址 / 运输标签”

  • 网络层:解析 IP 头部,检查 IP 地址是否是本机,去掉 IP 头部,交给对应的传输层协议(比如 TCP)。
  • 传输层:解析 TCP 头部,通过端口号找到对应的 socket(比如 HTTP 的 80 端口对应浏览器的 socket),去掉 TCP 头部,把应用数据放到 socket 的 “接收队列” 中。

5. 应用层:“签收快递”

当应用程序调用read()recv(),就会从 socket 的接收队列中取出数据,从内核态切换回用户态 —— 这时候应用程序终于拿到了网络包中的内容。

三、Linux 网络栈的 “高效秘诀”

整个收发流程能跑起来,靠的是内核模块的 “分工协作”:

  • sk_buff 的零拷贝:通过指针移动管理包,避免数据反复拷贝,节省 CPU 和内存。
  • 中断分工:硬中断快速接包,软中断后台处理,平衡了响应速度和处理效率。
  • 分层协议栈:每一层只做自己的事(比如 TCP 管可靠传输,IP 管路由),既清晰又易扩展。

四、关键组件职责清单

组件 核心职责
应用层 发起网络请求(调用send()/write())或接收数据(调用read()/recv()
Socket 层 作为用户态与内核态的接口,封装sk_buff缓冲区,衔接应用与协议栈
传输层(TCP/UDP) TCP:添加头部(端口、序号等),保证可靠 / 有序传输;UDP:简单封装,无连接传输
网络层(IP) 选择路由(确定下一跳),添加 IP 头部(源 / 目的 IP),实现跨网段转发
链路层 通过 ARP 查询 MAC 地址,添加以太网头部,处理局域网内的帧传输
网卡 发送时将sk_buff转为电 / 光信号;接收时捕获信号并拷贝到内核缓冲区
硬中断 网卡接收包后触发,快速完成数据拷贝,避免占用 CPU 过长
软中断(ksoftirqd) 后台处理拆包、协议解析、数据分发,提升整体处理吞吐量
sk_buff 内核中网络包的载体,通过指针操作实现高效封装 / 解封装,避免数据拷贝
路由表 存储网络路由规则,为发送流程提供 “下一跳” 决策依据
ARP 缓存 缓存 IP 与 MAC 的映射关系,避免重复广播查询,加速链路层封装

从应用层的一个send(),到网卡的电信号发送;从网卡的硬中断,到应用层的read()——Linux 网络包的旅程,是内核 “流水线式协作” 的最佳体现。每个组件各司其职,又紧密配合,才让网络通信高效、可靠地运转。

目录
相关文章
|
Ubuntu Linux C++
Ubuntu20.4配置arm交叉编译环境
我是在虚拟机中配置的,如果你的嵌入式设备足够完成自己的编译,可以不考虑虚拟机的。
1949 0
|
监控 Kubernetes 负载均衡
spring boot应用优化,6s内启动,内存减半
taptap-developer是一个spring boot框架驱动的纯Grpc服务,所以,只用了四步,移除了web和spring cloud相关的模块后,启动速度就稳稳的保持在了6s内。除了启动速度提升外,在服务待机状态下,内存锐减了50%左右,从500M左右的内存占用,缩减到了250M不到。
10218 113
spring boot应用优化,6s内启动,内存减半
|
2月前
|
Linux 网络安全
一文读懂NAT:SNAT与DNAT的“庐山真面目”及firewalld实战配置
本文详解NAT核心技——SNAT与DNAT,通过生活类比解析地址转换原理。针对不同系统版本,分别介绍firewalld新旧版配置方法:旧版用Direct接口,新版推荐Policy策略模式,涵盖命令示例与验证方式,助你轻松实现内网共享上网与服务发布。
|
存储 消息中间件 算法
深入解析OpenStack Cinder:块存储服务详解
本文介绍了OpenStack及其块存储服务Cinder。OpenStack是一个开源云计算管理平台,提供基础设施即服务(IaaS),核心服务包括计算、网络、存储等。Cinder主要用于为虚拟机提供持久性块存储,具备多种功能,如卷操作、备份、快照及与实例的交互等。此外,还详细介绍了Cinder的工作流程、命令行操作及不同存储插件的使用。
2029 8
|
存储 缓存 网络协议
深入理解Linux网络——内核是如何发送网络包的
一、相关实际问题 1. 查看内核发送数据消耗的CPU时应该看sy还是si 2. 在服务器上查看/proc/softirqs,为什么NET_RX要比NET_TX大得多 3. 发送网络数据的时候都涉及那些内存拷贝操作 4. 零拷贝到底是怎么回事 5. 为什么Kafka的网络性能很突出
|
机器学习/深度学习 编解码 自然语言处理
文生图大模型
DALL·E 是由 OpenAI 开发的基于深度学习的图像生成模型,能够根据文本描述生成原创图像。从 2021 年初的 DALL·E 到 2022 年的 DALL·E 2,再到最新的 DALL·E 3,其功能不断升级,包括生成、扩展、修改图像及生成变体图像。DALL·E 3 在提示优化、清晰度和多风格支持方面进行了增强,广泛应用于定制图像生成、虚拟设定、产品设计和广告营销等领域。
|
存储 监控 Cloud Native
剖析Linux网络包接收过程:掌握数据如何被捕获和分发的全过程(上)
剖析Linux网络包接收过程:掌握数据如何被捕获和分发的全过程
|
Kubernetes 网络协议 Cloud Native
Kubernetes网络问题排查分享两则(1)——calico特定场景下的网络性能问题
在对Kubernetes项目[kosmos](https://github.com/kosmos-io/kosmos)与Calico网络性能进行对比测试时,发现kosmos在跨集群容器网络的性能显著优于Calico的集群内网络(约6Gbit/s对比2.9Gbit/s)。物理机网络测试达到9.38Gbit/s,显示Calico有68%的性能损耗。问题定位到网卡的checksum/offload参数,尝试用`ethtool`调整后虽短暂提升,但随后恢复原状。转载自:https://mp.weixin.qq.com/s/XsQZCSqZAXJK46zqc7IpLw
|
KVM 虚拟化 数据安全/隐私保护
KVM虚拟机安装实战
本文讲述了如何创建并使用VNC连接KVM虚拟机的详细教程,包括安装图解和命令行参数说明。
582 8

热门文章

最新文章