讲师中心 微信公众号
AI工具推荐 视频效率加速

Linux 网络栈的基本结构

夏芳大大_4483

夏芳大大_4483

发布时间:2026-01-25 18:52:02

|

784人浏览过

|

来源于php中文网

原创

Linux内核网络栈分为链路层、网络层、传输层、套接字层四层;每层通过sk_buff指针操作实现零拷贝,依赖struct sock标识连接,驱动经NAPI或中断将包送入netif_receive_skb()启动协议处理。

linux 网络栈的基本结构

Linux 网络栈分哪几层?不是 OSI,是内核实际跑的四层

Linux 内核网络栈按功能划分为四层:链路层、网络层、传输层、套接字层(应用层逻辑由用户进程实现,不属内核栈)。这不是教科书式的 OSI 七层映射,而是内核数据流穿行的真实路径。每层对应一组核心数据结构和处理函数,sk_buff 是贯穿全程的“数据包载体”,它不存数据本身,只通过指针管理缓冲区头尾,各层仅移动指针、增删头部,避免拷贝。

  • 链路层:处理 ethhdr、ARP 请求/响应,驱动收包后调用 netif_receive_skb() 入栈;发包前调用 dev_queue_xmit()
  • 网络层:核心是 ip_rcv() 和 ip_forward(),查 FIB 路由表(ip route show 查看)、做分片/重组、校验 IP 头
  • 传输层:TCP 用 tcp_v4_rcv(),UDP 用 udp_rcv();端口查找靠 inet_hashinfo 结构,连接状态存在 struct sock 中
  • 套接字层:所有系统调用入口,如 bind()、connect()、sendmsg() 最终都落到 sock->ops->xxx 函数指针上

sk_buff 是什么?为什么改错指针位置就丢包

sk_buff 是 Linux 网络栈的“命脉”——它不是数据容器,而是一个带多组指针(head/data/tail/end)的元结构。数据真正存在 DMA 分配的内存页里,sk_buff 只负责告诉各层:“当前有效数据从哪开始、到哪结束”。一旦某层(比如 TCP)在封装时没调用 skb_push() 扩展 data 指针,或错误调用 skb_pull() 导致 data > tail,后续层读取时就会越界或读空,表现为静默丢包、tcpdump 能抓到入包但应用层收不到。

Skill Weave Chains — 技能链路由引擎
Skill Weave Chains — 技能链路由引擎

开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。

下载
  • 典型坑:skb_reserve(skb, ETH_HLEN) 必须在驱动收包后立即调用,否则以太网头会覆盖 IP 头
  • 调试技巧:用 skb_dump() 或在 netdev_rx_handler_register() 回调里打印 skb->len 和 skb_headlen(skb) 判断数据是否被意外截断
  • 注意:NAPI 轮询中,一个 sk_buff 可能被多个 CPU 并发访问,不能裸改指针而不加锁或使用 per-CPU 变量

网卡驱动怎么把包交给协议栈?别只盯着 ifconfig

物理网卡收包不是靠 ifconfig 或 ip link 启动的,而是靠驱动注册中断处理函数(如 e1000_intr())或 NAPI poll 函数(如 e1000_clean())。当网卡 DMA 完成,触发硬中断 → 内核调度软中断 NET_RX_SOFTIRQ → 执行 net_rx_action() → 调用驱动的 poll 方法批量收包 → 对每个包调用 netif_receive_skb() 进入协议栈。这个链条一旦断裂(比如驱动未启用 NAPI、net.core.netdev_budget 设太小),就会看到 /proc/net/dev 中 RX 计数增长但 netstat -s | grep -i "packet receive" 不变——包卡在驱动队列没进栈。

  • 验证是否进栈:运行 cat /proc/interrupts | grep eth0 看中断是否上升;再执行 watch -n1 'cat /proc/net/snmp | grep -A1 Tcp' 观察 TcpInSegs 是否同步增加
  • 常见误操作:用 ethtool -K eth0 gso off 关闭 GSO 后,大包在传输层被分片,若 MTU 配置不当,可能触发链路层反复重传
  • 虚拟网卡(如 veth)无中断,走的是直接函数调用路径:dev_hard_start_xmit() → dev->netdev_ops->ndo_start_xmit() → 直接送入对端 sk_buff 队列

为什么 socket() 创建的 fd 能跨层通信?关键在 struct sock

用户调用 socket(AF_INET, SOCK_STREAM, 0) 时,内核分配一个 struct socket(含文件描述符接口)并关联一个 struct sock(含协议控制块)。后者才是协议栈真正的“身份凭证”:TCP 层的 tcp_v4_rcv() 收到包后,用五元组(源IP/端口、目的IP/端口、协议)查哈希表,找到匹配的 struct sock,再把包塞进它的接收队列 sk->sk_receive_queue。应用层 recv() 实际就是从这个队列里取包。

  • 所以 bind() 的端口、listen() 的 backlog、setsockopt() 的 TCP_NODELAY,全作用于 struct sock 字段,而非文件描述符本身
  • 陷阱:多个线程同时 recv() 同一个 TCP socket,不会竞争 sk_receive_queue —— 因为内核已用 sk_lock 保护,但若用 SO_REUSEPORT 创建多个 socket 绑定同一端口,每个 socket 有独立队列,负载不均时需用 reuseport + BPF 做分流
  • 查看真实状态:ss -i 显示每个 socket 的 rcv_ssthresh、cwnd 等字段,比 netstat 更贴近内核视角
内核网络栈不是静态模型,而是一条高速流水线:sk_buff 是传送带,struct sock 是工位编号,驱动和协议函数是机械臂。任何一层指针偏移、队列溢出、哈希冲突或锁争用,都会让包在某个环节“掉下传送带”——而这种故障往往没有日志,只有 tcpdump 和 /proc/net/snmp 的数字差值在默默提醒你。

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

相关专题

更多
C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

299

2026.04.23

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2181

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

316

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

357

2026.01.06

C++ 数据结构与算法实现教程合集
C++ 数据结构与算法实现教程合集

以 C++ 为实现语言,系统讲解核心数据结构与算法,涵盖链表(单链表/双链表/环检测)、栈与队列(单调栈/优先队列)、二叉树(遍历/BST/AVL/红黑树)、哈希表(开地址法/链地址法)、图(邻接表/BFS/DFS/Dijkstra/拓扑排序)、常见排序算法(快排/归并/堆排/计数排序)的实现与复杂度分析,同时分享 LeetCode 刷题技巧、竞赛编程常用模板(二分/前缀和/滑动窗口/动态规划),帮助开发者夯实算法基础。

412

2026.05.09

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

3048

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

4309

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3689

2025.12.29

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

120

2026.09.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Valgrind支持平台说明
Valgrind支持平台说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn