当前位置: 首页 > news >正文

1.4.C++项目:仿muduo库实现并发服务器之buffer模块的设计

项目完整版在:

一、buffer模块: 缓冲区模块

在这里插入图片描述
Buffer模块是一个缓冲区模块,用于实现通信中用户态的接收缓冲区和发送缓冲区功能。

二、提供的功能

存储数据,取出数据

三、实现思想

1.实现换出去得有一块内存空间,采用vector ,vector底层是一个线性的内存空间!

(一)要素

1.默认空间大小
2.当前的读取数据位置!
3.当前的写入数据位置!

(二)操作

  1. 写入位置
    当前写入位置指向哪里,从哪里开始写入
    如果后续剩余空间不够了!
  2. 考虑整体缓冲区空闲空间是否足够!(因为读位置也会向后偏移,前后有可能有空闲空间)
    足够:将数据移动到起始位置
    不够:扩容,从当前写位置开始扩容足够大小!
    数据一旦写入成功,当前写位置,向后偏移!
  3. 读取数据
    当前的读取位置指向哪里,就从哪里开始读取,前提是有数据可读
    可读数据大小:当前写入位置,减去当前读取位置!

(三)框架设计

class buffer {private:std::vector<char> _buffer;// 位置是一个相对偏移量,而不是绝对地址!uint64_t _read_idx; // 读位置uint64_t _write_idx; // 写位置public:1. 获取当前写的位置2. 确保可写空间足够3. 获取前沿空间大小4. 获取后沿空间大小5. 将写入据位置向后移动指定长度6. 获取当前读取位置的地址!7. 获取可读空间大小8. 将读位置向后移动指定长度!9. clear

四、实现代码

#include <ctime>
#include <cstring>
#include <iostream>
#include <vector>
#include <cassert>
#include <string>
using namespace std;
#define BUFFER_SIZE 1024
class Buffer {private:std::vector<char> _buffer; // 使用vector进行内存空间管理uint64_t _read_idx; // 读偏移uint64_t _write_idx; // 写偏移public:Buffer():_read_idx(0),_write_idx(0),_buffer(BUFFER_SIZE) {}char* begin() {return &*_buffer.begin();}// 获取当前写入起始地址char *writePosition() { return begin() + _write_idx;}// 获取当前读取起始地址char *readPosition() { return begin() + _read_idx; }// 获取缓冲区末尾空间大小 —— 写偏移之后的空闲空间,总体大小减去写偏移uint64_t tailIdleSize() {return _buffer.size() - _write_idx; }// 获取缓冲区起始空间大小 —— 读偏移之前的空闲空间uint64_t handIdleSize() {return _read_idx ;}// 获取可读空间大小 = 写偏移 - 读偏移 uint64_t readAbleSize() {return _write_idx - _read_idx ;} // 将读偏移向后移动void moveReadOffset(uint64_t len) { // 向后移动大小必须小于可读数据大小assert(len <= readAbleSize());_read_idx += len; }// 将写偏移向后移动void moveWriteOffset(uint64_t len) { assert(len <= tailIdleSize());_write_idx += len;}void ensureWriteSpace(uint64_t len)  {// 确保可写空间足够 (整体空间够了就移动数据,否则就扩容!)  if (tailIdleSize() >= len) return;// 不够的话 ,判断加上起始位置够不够,够了将数据移动到起始位置if (len <= tailIdleSize() + handIdleSize()) {uint64_t rsz = readAbleSize(); //帮当前数据大小先保存起来std::copy(readPosition(),readPosition() + rsz,begin()); // 把可读数据拷贝到起始位置_read_idx = 0; // 读归为0_write_idx = rsz; // 可读数据大小是写的偏移量!}else { // 总体空间不够!需要扩容,不移动数据,直接给写偏移之后扩容足够空间即可!_buffer.resize(_write_idx + len);}}// 写入数据void Write(const void *data,uint64_t len) {ensureWriteSpace(len);const char *d = (const char*) data;std::copy(d,d + len,writePosition());}void WriteAndPush(void* data,uint64_t len) {Write(data,len);moveWriteOffset(len);}void WriteStringAndPush(const std::string &data) {writeString(data);moveWriteOffset(data.size());}void writeString(const std::string &data) {return Write(data.c_str(),data.size());}void writeBuffer(Buffer &data) {return Write(data.readPosition(),data.readAbleSize());}void writeBufferAndPush(Buffer &data) {writeBuffer(data);moveWriteOffset(data.readAbleSize());}std::string readAsString (uint64_t len) {assert(len <= readAbleSize());std::string str;str.resize(len);Read(&str[0],len);return str;}void Read(void *buf,uint64_t len) {// 读取数据 1. 保证足够的空间 2.拷贝数据进去// 要求获取的大小必须小于可读数据大小!assert(len <= readAbleSize());std::copy(readPosition(),readPosition() + len,(char*)buf);}void readAndPop(void *buf,uint64_t len) {Read(buf,len);moveReadOffset(len);}// 逐步调试!!!!!std::string ReadAsStringAndPop(uint64_t len) {assert(len <= readAbleSize());std::string str = readAsString(len);moveReadOffset(len);return str;}char* FindCRLF() {char *res = (char*)memchr(readPosition(),'\n',readAbleSize());return res;}// 通常获取一行数据,这种情况针对是:std::string getLine() {char* pos = FindCRLF();if (pos == NULL) {return "";}// +1 为了把换行数据取出来!return readAsString(pos - readPosition() + 1);}std::string getLineAndPop() {std::string str = getLine();moveReadOffset(str.size());return str;}void Clear() { // 清空缓冲区!clear// 只需要将偏移量归0即可!_read_idx = 0;_write_idx = 0;}
};

五、进行测试

#include "server.hpp"
using namespace std;
// 控制打印信息!!!
#define INF 0
#define DBG 1
#define ERR 2
#define LOG_LEVEL INF#define LOG(level,format,...) do{\if (level < LOG_LEVEL) break;\time_t t = time(NULL);\struct tm *ltm = localtime(&t);\char tmp[23] = {0};\strftime(tmp,31,"%H:%M:%S",ltm);\fprintf(stdout,"[%s,%s:%d] " format "\n",tmp,__FILE__,__LINE__,##__VA_ARGS__);\
}while(0)#define INF_LOG(format, ...) LOG(INF, format, ##__VA_ARGS__)
#define DBG_LOG(format, ...) LOG(DBG, format, ##__VA_ARGS__)
#define ERR_LOG(format, ...) LOG(ERR, format, ##__VA_ARGS__)int main() {Buffer buf;std::string str = "hello!";// buf.WriteStringAndPush(str);// Buffer buf1;// buf1.writeBufferAndPush(buf);// std::string tmp;// tmp = buf1.ReadAsStringAndPop(buf.readAbleSize());// cout << tmp << endl;// cout << buf.readAbleSize() << endl;// cout << buf1.readAbleSize() << endl;for (int i = 0; i < 300; i ++) {std::string str = "hello" + std::to_string(i) + '\n';buf.WriteStringAndPush(str);}while(buf.readAbleSize() > 0) {string line = buf.getLineAndPop();LOG("hello");  }// string tmp;// tmp = buf.ReadAsStringAndPop(buf.readAbleSize());// cout << tmp << endl;return 0;
}

中秋快乐!

相关文章:

1.4.C++项目:仿muduo库实现并发服务器之buffer模块的设计

项目完整版在&#xff1a; 一、buffer模块&#xff1a; 缓冲区模块 Buffer模块是一个缓冲区模块&#xff0c;用于实现通信中用户态的接收缓冲区和发送缓冲区功能。 二、提供的功能 存储数据&#xff0c;取出数据 三、实现思想 1.实现换出去得有一块内存空间&#xff0c;采…...

AndroidStudio精品插件集

官网 项目地址&#xff1a;Github博客地址&#xff1a;Studio 精品插件推荐 使用需知 所有插件在 Android Studio 2022.3.1.18&#xff08;长颈鹿&#xff09;上测试均没有问题&#xff0c;推荐使用此版本Android Studio 2022.3.1.18&#xff08;长颈鹿&#xff09;正式版下…...

java图书管理系统

一、 引言 图书管理系统是一个用于图书馆或书店管理图书信息、借阅记录和读者信息的应用程序。本系统使用Java Swing框架进行开发&#xff0c;提供直观的用户界面&#xff0c;方便图书馆管理员或书店工作人员对图书信息进行管理。以下是系统的设计、功能和实现的详细报告。 二…...

大屏自适应容器组件-Vue3+TS

1.引言 在做数字大屏时&#xff0c;图表能跟着浏览器的尺寸自动变化&#xff0c;本文采用Vue3前端框架&#xff0c;采用TypeScript语言&#xff0c;封装了一个大屏自适应组件&#xff0c;将需要显示的图表放入组件的插槽中&#xff0c;就能实现自适应屏幕大小的效果。 2.实际…...

java图书信息管理

一、项目概述 本图书信息管理系统旨在提供一个直观的用户界面&#xff0c;用于管理图书馆或书店的图书信息。系统包括图书添加、查询、借阅和归还等功能。 二、系统架构 系统采用JavaSwing作为前端UI框架&#xff0c;后端使用Java Servlet处理业务逻辑&#xff0c;数据存储在…...

apache服务器出现No input file specified.解决方案

APACHE服务器出现No input file specified.解决方案 thinkcmf程序默认的.htaccess里面的规则&#xff1a; <IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php/$1 [QSA…...

你写过的最蠢的代码是?——全栈开发篇

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…...

正点原子嵌入式linux驱动开发——TF-A初探

上一篇笔记中&#xff0c;正点原子的文档简单讲解了一下什么是TF-A&#xff0c;并且也学习了如何编译TF-A。但是TF-A是如何运行的&#xff0c;它的一个运行流程并未涉及。TF-A的详细运行过程是很复杂的&#xff0c;涉及到很多ARM处理器底层知识&#xff0c;所以这一篇笔记的内容…...

【网安别学成开发】之——python篇

经典入门编程题 1.猜数字 经典的猜数字游戏&#xff0c;几乎所有人学编程时都会做。 功能描述&#xff1a; 随机选择一个三位以内的数字作为答案。用户输入一个数字&#xff0c;程序会提示大了或是小了&#xff0c;直到用户猜中。 #!/usr/bin/env python3import randomresu…...

vue图片显示

一、Vue图片显示方法&#xff1a; 1.直接使用<img>标签&#xff1a; 最简单的方法是使用<img>标签&#xff0c;并将图片的URL作为src属性的值。例如&#xff1a; <img src"path/to/your/image.jpg" alt"Image"> 如果是绝对路径&#x…...

S32K144 GPIO编程

前面的文章介绍了如何在MDK-Keil下面进行S32K144的开发&#xff0c;下面就使用该工程模板进行GPIO LED的编程试验。 1. 开发环境 S32K144EVB-Q100开发板MDK-Keil Jlink 2. 硬件连接 S32K144EVB-Q100开发板关于LED的原理图如下&#xff1a; 也就是具体连接关系如下&#xf…...

域名备案流程(个人备案,腾讯云 / 阿里云)

文章目录 1.网站备案的目的2.备案准备的材料2.1 网站域名2.2 云资源或备案授权码2.3 电子材料 3.首次个人备案准备的材料3.1 主体相关3.2 域名相关3.3 网站相关3.4 网站服务相关3.5 变更相关 4.个人备案流程4.1 登录系统4.2 填写备案信息&#x1f340; 填写备案省份&#x1f34…...

子网ip和子网掩码的关系

子网ip和子网掩码的关系 一个IP地址被分为两部分&#xff1a;网络地址和主机地址。这是通过子网掩码来实现的。 子网掩码&#xff08;Subnet Mask&#xff09;是一个32位的二进制数&#xff0c;它用来区分一个IP地址中的网络地址和主机地址。在子网掩码中&#xff0c;网络地址…...

openGauss学习笔记-88 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用将磁盘表转换为MOT

文章目录 openGauss学习笔记-88 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用将磁盘表转换为MOT88.1 前置条件检查88.2 转换88.3 转换示例 openGauss学习笔记-88 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用将磁盘表转换为MOT …...

网络-Ajax

文章目录 前言一、Ajax优点&#xff1a;缺点&#xff1a; 二、使用步骤XNLHttpRequest对象完整代码 总结 前言 本文主要记录Ajax技术的简介&#xff0c;以及用法。 一、Ajax Ajax是一组用于在Web浏览器和Web服务器之间进行异步通信的Web开发技术。 它代表着Asynchronous Java…...

Autowired和Resource的关系

相同点对于下面的代码来说&#xff0c;如果是Spring容器的话&#xff0c;两个注解的功能基本是等价的&#xff0c;他们都可以将bean注入到对应的field中 不同点但是请注意&#xff0c;这里说的是基本相同&#xff0c;说明还是有一些不同点的&#xff1a; byName和byType匹配顺…...

HashTable, HashMap, ConcurrentHashMap 之间的区别

HashMap: 线程不安全. key 允许为 null。 Hashtable: 线程安全. 使用 synchronized 锁 Hashtable 对象, 效率较低. key 不允许为 null.。只是简单的把关键方法上加上了 synchronized 关键字。如 get 和 set &#xff0c;这相当于直接针对 Hashtable 对象本身加锁&#xff0c;如…...

Maven下载源码出现:Cannot download sources Sources not found for org.springframwork...

Maven下载源码出现&#xff1a;Cannot download sources Sources not found for org.springframwork… 最近重装了IDEA再次查看源码时发现总是报错&#xff0c;网上找了很多&#xff0c;发现解决方法都是在项目终端执行如下命令&#xff1a; mvn dependency:resolve -Dclassi…...

C进阶--字符函数和字符串函数介绍

✨ 更多细节参考 cplusplus.com/reference/cstring/ 使用方式&#xff1a; ⭕ 求字符串长度 &#x1f58c; strlen 函数原型&#xff1a; size_t strlen ( const char * str ); 作用&#xff1a; 获取字符串长度 ✨补充&#xff1a; ⭐字符串以 \0 作为结束标志&…...

算法通关村第五关-二叉树遍历(层数优先)之经典问题:简单的层序遍历、层序遍历分层、自底向上的层序遍历

基础知识&#xff08;青铜挑战&#xff09; 了解二叉树的基础知识 实战训练&#xff08;白银挑战&#xff09; 简单的层序遍历 基本的层序遍历思路很清晰&#xff1a; 给你一个二叉树根节点&#xff0c;你需要创建一个队列 queue 来遍历节点&#xff0c;一个链表 list 来存储…...

信创实践:Nacos 2.4.1 与人大金仓 Kingbase 的深度适配与性能调优

1. 为什么需要从MySQL迁移到人大金仓Kingbase&#xff1f; 最近几年&#xff0c;国产数据库的发展速度确实让人惊喜。作为一线开发者&#xff0c;我亲身体验了从MySQL迁移到人大金仓Kingbase的全过程。说实话&#xff0c;刚开始心里也没底&#xff0c;毕竟MySQL用得太顺手了。但…...

3步打造Windows字体终极体验:MacType高清渲染全攻略

3步打造Windows字体终极体验&#xff1a;MacType高清渲染全攻略 【免费下载链接】mactype Better font rendering for Windows. 项目地址: https://gitcode.com/gh_mirrors/ma/mactype 一、视觉痛点全解析&#xff1a;谁在忍受模糊字体的煎熬&#xff1f; 设计师的色彩…...

RWKV7-1.5B-G1A入门实战:手把手教你写文案、做总结、玩对话

RWKV7-1.5B-G1A入门实战&#xff1a;手把手教你写文案、做总结、玩对话 1. 认识RWKV7-1.5B-G1A RWKV7-1.5B-G1A是一个基于RWKV-7架构的多语言文本生成模型&#xff0c;特别适合处理基础问答、文案续写、简短总结和轻量中文对话任务。这个1.5B参数的模型在保持良好生成质量的同…...

OpenClaw故障自愈方案:Qwen3-32B镜像异常重启监控

OpenClaw故障自愈方案&#xff1a;Qwen3-32B镜像异常重启监控 1. 问题背景与解决思路 上周我的OpenClaw自动化助手突然"罢工"了——原本应该定时执行的日报生成任务没有按时完成。排查后发现是底层Qwen3-32B模型服务因OOM异常退出。这种情况在长期运行的AI服务中并…...

Elasticsearch踩坑记录:scaled_float字段查询结果和你想的不一样?

Elasticsearch中的scaled_float&#xff1a;为什么你的查询结果总是不准确&#xff1f; 刚接触Elasticsearch的开发者经常会遇到一个令人困惑的现象&#xff1a;明明存储的是精确的浮点数&#xff0c;查询时却返回了意料之外的结果。这背后往往与scaled_float字段类型的特殊处理…...

智能家居控制中心:OpenClaw桥接Qwen3-32B-Chat与HomeAssistant

智能家居控制中心&#xff1a;OpenClaw桥接Qwen3-32B-Chat与HomeAssistant 1. 为什么需要AI驱动的家居控制中心 去年冬天的一个深夜&#xff0c;我被空调异常制热的噪音惊醒。摸黑在手机APP上反复调整参数无果后&#xff0c;突然意识到&#xff1a;如果有个能理解自然语言的智…...

告别向日葵和TeamViewer!用你家路由器自带的DDNS功能,免费搭建Windows远程桌面(保姆级教程)

告别第三方远程工具&#xff1a;用路由器DDNS解锁Windows远程桌面全速体验 每次打开向日葵或TeamViewer时&#xff0c;那个转圈加载的进度条是否让你眉头紧锁&#xff1f;当免费版突然弹出"会话时长已达上限"的提示时&#xff0c;是否恨不得砸键盘&#xff1f;作为常…...

零基础手写大模型

从零搭建大模型&#xff1a;零基础学习实现职业经济跃迁指南 引言 在人工智能重塑全球产业格局的今天&#xff0c;“大模型”已不再仅仅是科技巨头的专利&#xff0c;而是成为了数字经济时代新的“电力”与“石油”。对于广大职场人士、创业者及寻求转型的个体而言&#xff0…...

SYNBO AMA 回顾|当稳定币突破 3000 亿,一级的“钱”到底在往哪里流?

一、 聊了什么&#xff1a;背景与主题时间&#xff1a;2026 Mar 25 (Wed) 20:00 UTC8主题&#xff1a; Stablecoins Primary Market: The New Capital Stack Powering Global Payments in 2026在昨晚举行的一场围绕“稳定币、PayFi 与全球支付”的 AMA 中&#xff0c;SYNBO 与…...

League-Toolkit:基于LCU API的英雄联盟效率工具集

League-Toolkit&#xff1a;基于LCU API的英雄联盟效率工具集 【免费下载链接】League-Toolkit 兴趣使然的、简单易用的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit League-Toolkit是一…...