DPDK用户态协议栈-TCP Posix API 2
tcp posix api
send发送
ssize_t nsend(int sockfd, const void *buf, size_t len, __attribute__((unused))int flags) {ssize_t length = 0;void* hostinfo = get_host_fromfd(sockfd);if (hostinfo == NULL) {return -1;}struct ln_tcp_stream* stream = (struct ln_tcp_stream*)hostinfo;if (stream->proto == IPPROTO_TCP) {struct ln_tcp_fragment* fragment = rte_malloc("send frag", sizeof(struct ln_tcp_fragment), 0);if (fragment == NULL) {return 0;}memset(fragment, 0, sizeof(struct ln_tcp_fragment));fragment->sport = stream->dport;fragment->dport = stream->sport;fragment->acknum = stream->recv_next;fragment->seqnum = stream->send_next;fragment->windows = LN_TCP_INITIAL_WINDOWS;fragment->tcp_flags = RTE_TCP_ACK_FLAG | RTE_TCP_PSH_FLAG;fragment->hdr_off = 0x50;fragment->data = rte_malloc("frag data", len + 1, 0);if (fragment->data == NULL) {rte_free(fragment);return -1;}memset(fragment->data, 0, len + 1);rte_memcpy(fragment->data, buf, len);fragment->length = len;length = fragment->length;rte_ring_mp_enqueue(stream->send_next, (void*)fragment);}return length;
}
recv接收
ssize_t nrecv(int sockfd, void *buf, size_t len, __attribute__((unused))int flags) {ssize_t length = 0;void* hostinfo = get_host_fromfd(sockfd);if (hostinfo == NULL) {return -1;}struct ln_tcp_stream* stream = (struct ln_tcp_stream*)hostinfo;if (stream->proto == IPPROTO_TCP) {struct ln_tcp_fragment* fragment = NULL;int nb_rev = 0;pthread_mutex_lock(&stream->mutex);while((nb_rev = rte_ring_mc_dequeue(stream->recvbuf, (void**)&fragment)) < 0) {pthread_cond_wait(&stream->cond, &stream->mutex);}pthread_mutex_unlock(&stream->mutex);if (fragment->length > len) {rte_memcpy(buf, fragment->data, len);int i;for (i = 0; i < fragment->length - len; i++) {fragment->data[i] = fragment->data[i + len];}fragment->length = fragment->length - len;length = fragment->length;rte_ring_mp_enqueue(stream->recvbuf, (void*)fragment);}else if (fragment->length == 0) {rte_free(fragment);}else {rte_memcpy(buf, fragment->data, len);length = fragment->length;rte_free(fragment->data);fragment->data = NULL;rte_free(fragment);}}return length;
}
数据包收发管理管理
接收
static int ln_tcp_enqueue_recvbuf(struct ln_tcp_stream* stream, struct rte_tcp_hdr* tcphdr, int tcplen) {struct ln_tcp_fragment* fragment = rte_malloc("tcp frag", sizeof(struct ln_tcp_fragment));if (fragment == NULL) {return -1;}memset(fragment, 0, sizeof(struct ln_tcp_fragment));fragment->dport = ntohs(tcphdr->dst_port);fragment->sport = ntohs(tcphdr->src_port);uint8_t hdrlen = tcphdr->data_off >> 4;int payloadlen = tcplen - hdrlen * 4;if (payloadlen > 0) {uint8_t* payload = (uint8_t*)tcphdr + hdrlen * 4;fragment->data = rte_malloc("frag data", payloadlen + 1, 0);if (fragment->data == NULL) {rte_free(fragment);return -1;}memset(fragment, 0, payloadlen + 1);rte_memcpy(fragment->data, payload, payloadlen);fragment->length = payloadlen;}else if (payloadlen == 0) {fragment->length = 0;fragment->data = NULL;}rte_ring_mp_enqueue(stream->recvbuf, (void*)fragment);pthread_mutex_lock(&stream->mutex);pthread_cond_signal(&stream->cond);pthread_mutex_unlock(&stream->mutex);return 0;
}
发送
static int ln_tcp_send_ackpkt(struct ln_tcp_stream* stream, struct rte_tcp_hdr* tcphdr) {struct ln_tcp_fragment* fragment = rte_malloc("ack frag", sizeof(struct ln_tcp_fragment), 0);if (fragment == NULL) {return -1;}memset(fragment, 0, sizeof(struct ln_tcp_fragment));fragment->sport = stream->dport;fragment->dport = stream->sport;fragment->acknum = stream->recv_next;fragment->seqnum = stream->send_next;fragment->windows = LN_TCP_INITIAL_WINDOWS;fragment->length = 0;fragment->data = NULL;fragment->hdr_off = 0x50;fragment->tcp_flags = RTE_TCP_ACK_FLAG;rte_ring_mp_enqueue(stream->sendbuf, (void*)fragment);return 0;
}
establish handle
static int ln_tcp_handle_close_established(struct ln_tcp_stream* stream, struct rte_tcp_hdr* tcphdr, int tcplen) {if (tcphdr->tcp_flags & RTE_TCP_SYN_FLAG) {}if (tcphdr->tcp_flags & RTE_TCP_PSH_FLAG) {ln_tcp_enqueue_recvbuf(stream, tcphdr, tcplen);uint8_t hdrlen = tcphdr->data_off >> 4;int payloadlen = tcphdr - hdrlen * 4;stream->recv_next = stream->recv_next + payloadlen;stream->send_next = ntohl(tcphdr->recv_ack);ln_tcp_send_ackpkt(stream, tcphdr);}if (tcphdr->tcp_flags & RTE_TCP_ACK_FLAG) {}if (tcphdr->tcp_flags & RTE_TCP_FIN_FLAG) {stream->status = LN_TCP_STATUS_CLOSE_WAIT;ln_tcp_enqueue_recvbuf(stream, tcphdr, tcphdr->data_off >> 4);stream->recv_next = stream->recv_next + 1;stream->send_next = ntohl(tcphdr->recv_ack);ln_tcp_send_ackpkt(stream, tcphdr);}return 0;
}
tcp server
static int tcp_server_entry(__attribute__((unused)) void* arg) {int sockfd = nsocket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0) {return -1;}printf("tcp sockfd is %d\n", sockfd);struct sockaddr_in servaddr;memset(&servaddr, 0, sizeof(struct sockaddr));servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_family = AF_INET;servaddr.sin_port = htons(8888);nbind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr));nlisten(sockfd, 10);while (1) {struct sockaddr_in client;socklen_t len = sizeof(client);int connfd = naccept(sockfd, (struct sockaddr*)&client, &len);char buff[BUFFER_SIZE] = {0};while (1) {int n = nrecv(connfd, buff, BUFFER_SIZE, 0); // blockif (n > 0) {printf("recv: %s\n", buff);nsend(connfd, buff, n, 0);}else if (n == 0) {nclose(connfd);break;}else {//nonblock}}}nclose(sockfd);
}
效果展示
回去之后调好了,有点难调

总结
到目前为止,IP/TCP和IP/UDP的协议栈都写完了,但是没有并发效果;这个后面会解决。下一步是探索一下协议的扩展,写一个dns服务器来看一下如何基于tcp或者udp来扩展协议。
项目地址
项目地址
参考资料:https://github.com/0voice
相关文章:
DPDK用户态协议栈-TCP Posix API 2
tcp posix api send发送 ssize_t nsend(int sockfd, const void *buf, size_t len, __attribute__((unused))int flags) {ssize_t length 0;void* hostinfo get_host_fromfd(sockfd);if (hostinfo NULL) {return -1;}struct ln_tcp_stream* stream (struct ln_tcp_stream…...
[IT项目管理]项目时间管理(本章节3w字爆肝)
七.项目时间管理 7.1 项目进度的重要性 为什么要重视项目进度:在项目进行的过程之中会遇到变故。但是不论项目中发生了什么,时间总是在流逝,就可能会导致项目不可以在规定的时间完成。 7.2可能影响项目进度的因素 有员工离职个人的工作方…...
【python因果库实战5】使用银行营销数据集研究营销决策的效果5
目录 接触次数的效应 重新定义治疗变量和潜在混杂因素 更深入地审视干预情景 逆概率加权 标准化 总结及与非因果分析的比较 接触次数的效应 我们现在转而研究当前营销活动中接触次数的数量(campaign)对积极结果发生率的影响。具体来说,…...
【Qt】QWidget中的常见属性及其功能(二)
目录 六、windowOpacity 例子: 七、cursor 例子: 八、font 九、toolTip 例子: 十、focusPolicy 例子: 十一、styleSheet 计算机中的颜色表示 例子: 六、windowOpacity opacity是不透明度的意思。 用于设…...
9 OOM和JVM退出。OOM后JVM一定会退出吗?
首先我们把两个概念讲清楚 OOM是线程在申请堆内存,发现堆内存空间不足时候抛出的异常。 JVM退出的条件如下: java虚拟机在没有守护线程的时候会退出。守护线程是启动JVM的线程,服务于用户线程。 我们简单说下守护线程的功能: 1.日志的记录…...
学习笔记070——Java中【泛型】和【枚举】
文章目录 1、泛型1.1、为什么要使用泛型?1.2、泛型的应用1.3、泛型通配符1.4、泛型上限和下限1.5、泛型接口 2、枚举 1、泛型 Generics 是指在定义类的时候不指定类中某个信息(属性/方法返回值)的具体数据类型,而是用一个标识符来…...
【工具变量】碳排放市场交易数据(2013-2023年)
一、时间范围:2013年8月5日到2023年1月13日 二、具体指标: 交易日期 城市名称 交易品种 开盘价 最高价 最低价 成交均价 收盘价 前收盘价 涨跌幅 总成交量 总成交额 …...
【视频生成模型】——Hunyuan-video 论文及代码讲解和实操
🔮混元文生视频官网 | 🌟Github代码仓库 | 🎬 Demo 体验 | 📝技术报告 | 😍Hugging Face 文章目录 论文详解基础介绍数据预处理 (Data Pre-processing)数据过滤 (Data Filtering)数据标注 (Data…...
基线检查:Windows安全基线.【手动 || 自动】
基线定义 基线通常指配置和管理系统的详细描述,或者说是最低的安全要求,它包括服务和应用程序设置、操作系统组件的配置、权限和权利分配、管理规则等。 基线检查内容 主要包括账号配置安全、口令配置安全、授权配置、日志配置、IP通信配置等方面内容&…...
uniapp跨端适配—条件编译
在uniapp中,跨端适配是通过条件编译实现的。条件编译允许开发者根据不同的平台(如iOS、Android、微信小程序、百度小程序等)编写不同的代码。这样可以确保每个平台上的应用都能得到最优的性能和用户体验。 以下是uniapp中条件编译的基本语法…...
【Java基础面试题013】Java中静态方法和实例方法的区别是是么?
回答重点 静态方法 使用static关键字修修饰的方法属于类随着类的加载而加载,随着类的卸载而消失可以通过类名直接调用,也可以通过对象调用,但是这种方式不推荐,会混淆意义,也不利于后期维护与扩展 class Example {st…...
C语言入门(一):A + B _ 基础输入输出
前言 本专栏记录C语言入门100例,这是第(一)例。 目录 一、【例题1】 1、题目描述 2、代码详解 二、【例题2】 1、题目描述 2、代码详解 三、【例题3】 1、题目描述 2、代码详解 四、【例题4】 1、题目描述 2、代码详解 一、【例…...
Vue日历组件FullCalendar使用方法
FullCalendar (全日历)Vue组件的使用 FullCalendar官方文档地址 FullCalendar日历组件支持Vue React Angular Javascript Vue2的框架示例: npm install --save fullcalendar/core fullcalendar/vue<template><div class"cal…...
TinyML在OBD-II边缘设备上燃油类型分类的实现与优化
论文标题:TinyML Implementation and Optimization for Fuel Type Classification on OBD-II Edge Device(TinyML在OBD-II边缘设备上燃油类型分类的实现与优化) 作者信息:Miguel Amaral, Morsinaldo Medeiros, Matheus Andrade, …...
vue3 中 defineProps 声明示例
1、直接声明 // 1、直接使用 defineProps(["tableData", "acceptType"]); 2、运行时声明方式不使用TypeScript类型注解,而是使用JavaScript对象,使用 type 来定义props // 2、运行时声明方式不使用TypeScript类型注解,…...
SpringBoot整合MybatisPlus报错Bean不存在:NoSuchBeanDefinitionException
报错信息: Exception in thread “main” org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘com.feng.mybatisplusdemo.dao.UserMapper’ available 解决办法: 将原来引入的MybatisPlus依赖:…...
异步电机的控制是否还有研究的必要,是不是已经非常成熟了?
随着工业现代化和自动化进程的加快,异步电机作为最为常见的电动机之一,广泛应用于各类机械设备和工业自动化系统中。异步电机因其结构简单、成本低廉、维护方便等优点而备受青睐。 异步电机的基本原理与应用 异步电机,又称感应电机…...
【Android】解决 ADB 中 SELinux 设置与 `Failed transaction (2147483646)` 错误
解决 ADB 中 SELinux 设置与 Failed transaction (2147483646) 错误 在使用 ADB 进行开发和调试时,经常会遇到由于 Android 系统安全策略(SELinux)引起的权限问题,尤其是在执行某些操作时,可能会遇到类似 cmd: Failur…...
企业车辆管理系统(源码+数据库+报告)
一、项目介绍 352.基于SpringBoot的企业车辆管理系统,系统包含两种角色:管理员、用户,系统分为前台和后台两大模块 二、项目技术 编程语言:Java 数据库:MySQL 项目管理工具:Maven 前端技术:Vue 后端技术&a…...
SAP RESTful架构和OData协议
一、RESTful架构 RESTful 架构(Representational State Transfer)是一种软件架构风格,专门用于构建基于网络的分布式系统,尤其是在 Web 服务中。它通过利用 HTTP 协议和一组简单的操作(如 GET、POST、PUT、DELETE&…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
【若依】框架项目部署笔记
参考【SpringBoot】【Vue】项目部署_no main manifest attribute, in springboot-0.0.1-sn-CSDN博客 多一个redis安装 准备工作: 压缩包下载:http://download.redis.io/releases 1. 上传压缩包,并进入压缩包所在目录,解压到目标…...
MeshGPT 笔记
[2311.15475] MeshGPT: Generating Triangle Meshes with Decoder-Only Transformers https://library.scholarcy.com/try 真正意义上的AI生成三维模型MESHGPT来袭!_哔哩哔哩_bilibili GitHub - lucidrains/meshgpt-pytorch: Implementation of MeshGPT, SOTA Me…...
Appium下载安装配置保姆教程(图文详解)
目录 一、Appium软件介绍 1.特点 2.工作原理 3.应用场景 二、环境准备 安装 Node.js 安装 Appium 安装 JDK 安装 Android SDK 安装Python及依赖包 三、安装教程 1.Node.js安装 1.1.下载Node 1.2.安装程序 1.3.配置npm仓储和缓存 1.4. 配置环境 1.5.测试Node.j…...
