从零开始实现一个C++高性能服务器框架----序列化模块

news/2024/11/28 2:47:16/

此项目是根据sylar框架实现,是从零开始重写sylar,也是对sylar丰富与完善
项目地址:https://gitee.com/lzhiqiang1999/server-framework

简介

项目介绍:实现了一个基于协程的服务器框架,支持多线程、多协程协同调度;支持以异步处理的方式提高服务器性能;封装了网络相关的模块,包括socket、http、servlet等,支持快速搭建HTTP服务器或WebSokcet服务器。
详细内容:日志模块,使用宏实现流式输出,支持同步日志与异步日志、自定义日志格式、日志级别、多日志分离等功能。线程模块,封装pthread相关方法,封装常用的锁包括(信号量,读写锁,自旋锁等)。IO协程调度模块,基于ucontext_t实现非对称协程模型,以线程池的方式实现多线程,多协程协同调度,同时依赖epoll实现了事件监听机制。定时器模块,使用最小堆管理定时器,配合IO协程调度模块可以完成基于协程的定时任务调度。hook模块,将同步的系统调用封装成异步操作(accept, recv, send等),配合IO协程调度能够极大的提升服务器性能。Http模块,封装了sokcet常用方法,支持http协议解析,客户端实现连接池发送请求,服务器端实现servlet模式处理客户端请求,支持单Reator多线程,多Reator多线程模式的服务器。

序列化模块

  • 序列化模块的底层存储是固定大小的块,以链表形式组织。每次写入数据时,将数据写入到链表最后一个块中,如果最后一个块不足以容纳数据,则分配一个新的块并添加到链表结尾,再写入数据。ByteArray会记录当前的操作位置,每次写入数据时,该操作位置按写入大小往后偏移,如果要读取数据,则必须调用setPosition重新设置当前的操作位置。
  • 这样有个好处,不用一开始就开一个很大的空间去存储数据。

1. 主要功能

  • 支持序列化固定长度的有符号/无符号8位、16位、32位、64位整数
  • 支持序列化不固定长度的有符号/无符号32位、64位整数(使用zigzag算法进行压缩)
  • 支持序列化float、double类型
  • 支持序列化string和(length+string)的格式
  • 支持将序列化内容输出到文件
  • 支持大小端转换

2. 功能演示

std::vector<int32_t> res; 
johnsonli::ByteArray::ptr ba(new johnsonli::ByteArray(base_len)); 
for(int i = 0; i<len; ++i) { res.push_back(rand()); 
} 
for(auto &it : res)  { ba->writeFint32(it); 
} 
ba->setPosition(0); 	// 读之前偏移量要设置为0
for(auto it : res) { int32_t val = ba->readFint32(); DO_ASSERT(it == val); 
} 
DO_ASSERT(ba->getReadSize() == 0);  
LOG_INFO(g_logger) << "writeFint32/readFint32" " (int32_t) len=" << len << " base_len=" << base_len << " size=" << ba->getSize(); 

3. 模块介绍

3.1 ByteArray

  • 序列化类。封装一个内存块,使用链表将内存块连接,实现动态扩容
struct Node
{Node(size_t s);		//构造指定大小的内存块Node();~Node();char* ptr;      	//内存块地址指针           Node* next;     	//下一个内存块地址size_t size;    	//内存块大小
};
  • 主要支持以下方法
void writeFint8  (int8_t value);   	// 写入固定长度int8_t类型的数据
void writeFuint8 (uint8_t value);	// 写入固定长度uint8_t类型的数据
// ... 16、32、64字节
void writeInt32  (int32_t value);	// 压缩写入int32_t 
void writeUint32 (uint32_t value);	// 压缩写入uint32_t 
// 64字节void writeFloat  (float value);
void writeDouble(float value);void writeStringF16(const std::string& value);				// 写入std::string类型的数据,用uint16_t作为长度类型
void writeStringWithoutLength(const std::string& value);	// 不写长度
// ...void readFint8  (int8_t value);   	// 读取固定长度int8_t类型的数据
void readFuint8 (uint8_t value);	// 读取固定长度uint8_t类型的数据
// ... 16、32、64字节
void readInt32  (int32_t value);	// 读取压缩的int32_t 
void readUint32 (uint32_t value);	// 读取压缩的uint32_t 
// 64字节...
  • 长度+string的编码发送方式类似于TLV编码

http://www.ppmy.cn/news/39294.html

相关文章

2023 年前端十大 Web 趋势

在本文中&#xff0c;我想跟大家聊聊自己看到的最新 Web 开发趋势。 &#xff08;元&#xff09;框架 单页应用程序&#xff08;SPA&#xff09;及各类相关框架&#xff08;包括 React.js、Vue.js、Svelte.js 等&#xff09;或多或少都经历过一定的炒作周期&#xff0c;也用多…

深度优先搜索算法详解

深度优先搜索&#xff08;Depth-First Search&#xff0c;DFS&#xff09;是一种经典的图形搜索算法&#xff0c;用于在图或树中遍历所有节点。它是一种递归算法&#xff0c;它通过深入到树或图的最深层来遍历节点&#xff0c;并且在回溯时继续搜索其他分支。 深度优先搜索的核…

从SE for AI 到AI for SE,谈无代码平台如何应用AIGC技术

ChatGPT爆⽕全⽹一段时间后&#xff0c;GPT4的发布再次打破普通人的认知。 相比于chatGPT聊天式交互和生成答案&#xff0c;其背后的底层技术AIGC应用场景更加广泛。不管是头部厂商还是个人&#xff0c;都在考虑如何借助这项新技能实现跨越式发展。 数睿数据也在思考无代码开…

半监督学习为什么能work?以及直推式学习是什么

今天在看半监督的时候&#xff0c;突然想起这个问题&#xff1a; 半监督用训好的模型去生成伪标签&#xff0c;再把伪标签当做真标签去训&#xff0c;但是模型能生成伪标签说明模型已经学到了这部分内容&#xff0c;把模型已经学会的内容加进去&#xff0c;让模型继续学&#…

大器晚成我服刘邦,48岁才开始创业

读史使人明智&#xff0c;周末放下手机&#xff0c;静下心来读点人文历史。大器晚成我最佩服刘邦&#xff0c;48岁才开始创业 。在此之前&#xff0c;他是一个出身平凡的农民&#xff0c;早年曾多次失败和受挫。刘邦最后能够战胜项羽&#xff0c;常常让人觉得匪夷所思&#xff…

网络编程三要素

网络编程三要素 IP、端口号、协议 三要素分别代表什么 ip&#xff1a;设备在网络中的地址&#xff0c;是唯一的标识 端口号&#xff1a;应用程序在设备中的唯一标识 协议&#xff1a;数据在网络中传输的规则 常见的协议有UDP、TCP、http、https、ftp ip&#xff1a;IPv4和…

DataGrip连接数据库设置(MySQL、Oracle、SQL Server)

一、DataGrip连接MySQL 1.1 配置信息 1.2 测试查询employees库中departments表信息 employees为测试库&#xff0c;具体来源&#xff0c;参考这篇文章 下载并导入MySQL示例数据库employees 。 1.3 测试查询employees库中employees表信息 二、DataGrip连接Oracle 将SID改为o…

Java中String类型的创建关系、什么是常量池、以及StringBuilder/Buffer等

Java的String字符串使用 String s1 "Hello World";String s2 "Hello World";String s3 new String("Hello World");String s4 new String("Hello World");System.out.println(s1s2); // trueSystem.out.println(s1s3); // falseSy…