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&…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...
ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...
Java数组Arrays操作全攻略
Arrays类的概述 Java中的Arrays类位于java.util包中,提供了一系列静态方法用于操作数组(如排序、搜索、填充、比较等)。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序(sort) 对数组进行升序…...
