尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
socket 内核收发数据解析
fd 和 socket 内核对象的关系socket 套接字,内核对象fd 只是访问它的编号一个 socket 内核对象包含1、发送缓冲区链表存放skb2、接收缓冲区链表存放skb3、五元组…用户态只能通过 fd 操作这个内核 socketLinux 一切皆文件fd 是 socket 在用户态的数字句柄send/recv/read/write// fd 本质进程 PCB (task_struct) 里的文件描述符表数组下标进程 task_struct └── files_struct 进程文件表 └── fd_array[]// fd就是数组索引fd0→ 指向structfile(标准输入)fd1→ 指向structfile(标准输出)fd4→ 指向socket对应的structfilefd--[进程fd数组]--structfile--structsocket// sk_buff 是内核数据包structsk_buff{structsk_buff*next;structsk_buff*prev;chardata[128];uint32_tlen;};/* 双向循环链表头节点 带头尾指针、长度、自旋锁是双向链表 FIFO 队列不是固定长度数组环形缓冲区 */structsk_buff_head{structsk_buff*next;structsk_buff*prev;__u32 qlen;// 当前队列skb数量pthread_spinlock_tlock;// 模拟内核spinlock_t自旋锁};// 双向循环链表基础操作// 初始化 sk_buff_head 双向循环链表头voidskb_queue_head_init(structsk_buff_head*q){q-next(structsk_buff*)q;q-prev(structsk_buff*)q;q-qlen0;pthread_spin_init(q-lock,PTHREAD_PROCESS_PRIVATE);}┌─────────────────────┐ │sk_buff_head(Q)│ │ │ ┌───────────►│ next │ │ │ prev │ │ │ qlen0│ │ └──────────┬────────────┘ │ │ └──────────────────────┘ Q.nextQ Q.prevQ # 文字描述哨兵头的 next、prev 都指向自己闭环没有真实skb数据包/* 多生产者但消费者队列模型 */#includestdio.h#includestdlib.h#includepthread.h#includestdint.h// 模拟 sk_buff 内核数据包structsk_buff{structsk_buff*next;structsk_buff*prev;chardata[128];// 数据包载荷uint32_tlen;};// 完全复刻截图struct sk_buff_headstructsk_buff_head{structsk_buff*next;structsk_buff*prev;__u32 qlen;// 当前队列skb数量pthread_spinlock_tlock;// 模拟内核spinlock_t自旋锁};// 双向循环链表基础操作 // 初始化 sk_buff_head 双向循环链表头voidskb_queue_head_init(structsk_buff_head*q){q-next(structsk_buff*)q;q-prev(structsk_buff*)q;q-qlen0;pthread_spin_init(q-lock,PTHREAD_PROCESS_PRIVATE);}// 队尾入队skb_queue_tail 内核真实API生产者往尾部追加skbvoidskb_queue_tail(structsk_buff_head*q,structsk_buff*skb){pthread_spin_lock(q-lock);// 双向循环链表插入尾部skb-prevq-prev;skb-next(structsk_buff*)q;q-prev-nextskb;q-prevskb;q-qlen;pthread_spin_unlock(q-lock);}// 队头出队skb_dequeue消费者从头部取出skbstructsk_buff*skb_dequeue(structsk_buff_head*q){pthread_spin_lock(q-lock);// 判断是否空队列循环链表头的next指向自己就是空if(q-next(structsk_buff*)q){pthread_spin_unlock(q-lock);returnNULL;}structsk_buff*skbq-next;q-nextskb-next;skb-next-prev(structsk_buff*)q;q-qlen--;pthread_spin_unlock(q-lock);returnskb;}// 释放skbvoidkfree_skb(structsk_buff*skb){if(skb)free(skb);}// 多生产者线程模拟用户态send/write #definePRODUCER_THREAD_NUM4structsk_buff_headg_tx_queue;// sk_write_queue socket发送队列void*producer_thread(void*arg){inttid*(int*)arg;for(inti0;i3;i){// 生产者分配skb填充数据插入队列尾部structsk_buff*skbmalloc(sizeof(structsk_buff));snprintf(skb-data,sizeof(skb-data),thread%d pkt-%d,tid,i);skb-lenstrlen(skb-data);skb_queue_tail(g_tx_queue,skb);printf([生产者线程%d] 入队: %s, queue qlen%u\n,tid,skb-data,g_tx_queue.qlen);}returnNULL;}// 单消费者线程模拟内核协议栈/应用read void*consumer_thread(void*arg){(void)arg;intconsume_cnt0;// 单消费者循环取包while(consume_cntPRODUCER_THREAD_NUM*3){structsk_buff*skbskb_dequeue(g_tx_queue);if(skbNULL){usleep(10000);// 队列为空短暂休眠continue;}printf([单消费者] 取出skb: %s\n,skb-data);kfree_skb(skb);consume_cnt;}printf([消费者] 全部处理完毕\n);returnNULL;}intmain(void){// 初始化 socket发送队列 sk_write_queueskb_queue_head_init(g_tx_queue);pthread_tproducers[PRODUCER_THREAD_NUM];inttids[PRODUCER_THREAD_NUM];pthread_tconsumer;// 启动多个生产者线程for(inti0;iPRODUCER_THREAD_NUM;i){tids[i]i;pthread_create(producers[i],NULL,producer_thread,tids[i]);}// 启动唯一消费者线程pthread_create(consumer,NULL,consumer_thread,NULL);// 等待全部线程结束for(inti0;iPRODUCER_THREAD_NUM;i){pthread_join(producers[i],NULL);}pthread_join(consumer,NULL);pthread_spin_destroy(g_tx_queue.lock);printf(程序结束最终队列长度 qlen%u\n,g_tx_queue.qlen);return0;}tx_ring/rx_ring/sk_write_queue/sk_read_queue 生产者消费者模型可以自行问 AI
RELATED

相关推荐

曲率感知零阶优化:大模型测试时适应的内存高效方案

曲率感知零阶优化:大模型测试时适应的内存高效方案

如果你正在部署一个大型预训练模型(比如大语言模型或视觉模型),并且发现它在你的特定业务数据上表现不佳,你可能会立刻想到“微调”。但微调意味着什么?意味着你需要准备大量标注数据、分配昂贵的GPU资源、等待漫长的训…

📅 2026/10/8 23:10:56
40岁适合做什么创业项目?

40岁适合做什么创业项目?

如果把“40岁创业”当成一个项目选择问题,可以先不讨论餐饮、电商、加盟、本地生活这些具体行业。先定义一个函数:Fit(Person, Project)输入是一个人的现有条件和一个创业项目的要求,输出是:这个项目到底适不适合当前这个人。这样…

📅 2026/9/11 10:37:54
Quartus内置ModelSim‑Altera报错Error: Failure to obtain a Verilog simulation license. Unable to checkout

Quartus内置ModelSim‑Altera报错Error: Failure to obtain a Verilog simulation license. Unable to checkout

quartus软件使用内置的ModelSim‑Altera仿真,总是报错,没有任何波形窗口 报错信息如下: ** Error: Failure to obtain a Verilog simulation license. Unable to checkout any of these license features: alteramtivsim or alteramtivlog. Error loading design Error: …

📅 2026/9/10 18:23:04
MORE NEWS

更多资讯

📰

SPI OLED改I2C接口:电阻跳线与接线全攻略

手里有块7针的SPI OLED屏,但手头主控板的SPI接口被别的外设占了,I2C倒是空着。换一块4针的I2C OLED吧,又要等快递;不换吧,这屏就这么躺着吃灰。后来我认真翻了翻屏背面丝印和数据手册,发现这事儿根本不用换…

📰

外贸客户开发:各国黄页渠道实操指南与高效搜索技巧

1. 外贸客户开发的底层逻辑与黄页渠道的核心价值做外贸这行十几年,我越来越觉得客户开发这件事本质上是一个概率游戏。你触达的潜在客户越多、越精准,成交的机会就越大。而黄页渠道,恰恰是这个概率游戏里被严重低估的一张牌。很多新人一上来就…

📰

Python邮件分类系统开题报告:TF-IDF与逻辑回归实战

简介:这是一份面向计算机专业毕业生的《基于Python的邮件分类系统》开题报告,适合正在筹备毕业论文开题、选择Web开发与机器学习方向的本专科学生参考,也适用于需要快速了解邮件分类系统整体架构的开发者。文档从垃圾邮件泛滥的现实问题切入&…

📰

基于机器视觉的害虫种类与数量检测:模型选型与工程落地避坑指南

简介:一份面向农业信息化与计算机视觉方向的毕业设计项目,完整实现了基于机器视觉的害虫种类及数量检测。资源包含Python源码、训练模型、昆虫图像数据集及文档,适合作为图像识别、数据分析类课题的参考。包体共165个文件,涵盖23个…

📰

GPU微架构代际划分:仿真验证与结构特征判定方法

1. 从“跑分提升”到“架构换代”的认知分水岭很多人第一次接触GPU仿真与微架构设计时,都会陷入一个特别朴素的判断标准:新卡比老卡跑分高,那就算新一代架构。这个判断在消费级市场勉强能用,但一旦进入微架构设计领域,…

📰

美术馆预约系统高并发设计与实战避坑指南

简介:本资源为一套完整的美术馆预约系统毕业设计项目源码,面向计算机专业本科生及Web全栈初学者,解决传统美术馆人工预约效率低、信息同步滞后、票务管理粗放等实际问题。压缩包共517个文件,涵盖109个Java后端逻辑文件、77个JavaS…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬