1、说明
缓冲区 cache 机制对于处理通信上,多包粘包的问题很有帮助,下面是使用数组实现环形队列 cache 机制的源码
2、源码
.h文件
//============================================================================
//============================================================================
//文件: cacheQue.h
//功能:
//说明: 环形队列的cache机制,用于解决粘包的情况
//版本: 1.0
//时间: 2024-12-24
//============================================================================
//============================================================================
#include<stdint.h>
#include<stdbool.h>
#ifndef CACHE_QUE_H
#define CACHE_QUE_H
#define CACHE_QUE_MAXLEN 65535
typedef struct{
uint8_t *pArray; //指向数组
uint16_t quefront; //队头下标
uint16_t queRear; //队尾下标
uint16_t maxlen; //总长度
uint16_t len; //当前长度
}CacheQue_st;
bool cacheQueInit(CacheQue_st *que, uint8_t *array, uint16_t len);
bool cacheQueRst(CacheQue_st *que);
bool cacheQueClear(CacheQue_st *que);
int cacheQueRemainlen_get(CacheQue_st *que);
int cacheQueCurrentlen_get(CacheQue_st *que);
bool cacheQuePush(CacheQue_st *que, uint8_t *data, uint16_t len);
bool cacheQuePop(CacheQue_st *que, uint8_t *buff, uint16_t len);
bool cacheQueGet(CacheQue_st *que, uint8_t *buff, uint16_t len);
bool cacheQueDelete(CacheQue_st *que, uint16_t len);
#endif
.c文件
//============================================================================
//============================================================================
//文件: cacheQue.c
//功能:
//说明: 环形队列的cache机制,用于解决粘包的情况
//版本: 1.0
//时间: 2024-12-24
//============================================================================
//============================================================================
#include"cacheQue.h"
#include<string.h>
//cache queue 初始化
bool cacheQueInit(CacheQue_st *que, uint8_t *array, uint16_t len)
{
if(que == NULL || array == NULL || len > CACHE_QUE_MAXLEN)
{
return false;
}
que->pArray = array;
que->quefront = 0;
que->queRear = 0;
que->maxlen = len;
que->len = 0;
return true;
}
//cache queue 重置
bool cacheQueRst(CacheQue_st *que)
{
if(que == NULL)
{
return false;
}
memset(que->pArray, 0, que->maxlen);
memset(que, 0, sizeof(CacheQue_st));
return true;
}
//cache queue 清空数据缓冲区
bool cacheQueClear(CacheQue_st *que)
{
if(que == NULL)
{
return false;
}
memset(que->pArray, 0, que->maxlen);
que->quefront = 0;
que->queRear = 0;
que->len = 0;
return true;
}
//获取剩余长度
int cacheQueRemainlen_get(CacheQue_st *que)
{
if(que == NULL)
{
return -1;
}
return (int)(que->maxlen - que->len);
}
//获取当前已有数据长度
int cacheQueCurrentlen_get(CacheQue_st *que)
{
if(que == NULL)
{
return -1;
}
return (int)que->len;
}
//入队
bool cacheQuePush(CacheQue_st *que, uint8_t *data, uint16_t len)
{
if(que == NULL || data == NULL || len > cacheQueRemainlen_get(que))
{
return false;
}
//队尾在前
if(que->queRear < que->quefront)
{
memcpy(&que->pArray[que->queRear + 1], data, len);
que->queRear += len;
que->len += len;
}
else
{
if(len <= (que->maxlen - 1 - que->queRear))
{
memcpy(&que->pArray[que->queRear + 1], data, len);
que->queRear += len;
que->len += len;
}
else
{
memcpy(&que->pArray[que->queRear + 1], data, (que->maxlen - 1 - que->queRear));
data += (que->maxlen - 1 - que->queRear);
memcpy(que->pArray, data, (len - (que->maxlen - 1 - que->queRear)));
que->queRear = (len - (que->maxlen - 1 - que->queRear)) - 1;
que->len += len;
}
}
return true;
}
//出队
bool cacheQuePop(CacheQue_st *que, uint8_t *buff, uint16_t len)
{
if(que == NULL || buff == NULL || len > cacheQueCurrentlen_get(que))
{
return false;
}
//队头在前
if(que->quefront < que->queRear)
{
memcpy(buff, &que->pArray[que->quefront], len);
memset(&que->pArray[que->quefront], 0, len);
que->quefront += len;
que->len -= len;
}
else
{
if(len <= (que->maxlen - que->quefront))
{
memcpy(buff, &que->pArray[que->quefront], len);
memset(&que->pArray[que->quefront], 0, len);
que->quefront += len;
que->len -= len;
}
else
{
memcpy(buff, &que->pArray[que->quefront], (que->maxlen - que->quefront));
memset(&que->pArray[que->quefront], 0, (que->maxlen - que->quefront));
memcpy(buff, que->pArray, (len - (que->maxlen - que->quefront)));
memset(que->pArray, 0, (len - (que->maxlen - que->quefront)));
que->quefront = len - (que->maxlen - que->quefront);
que->len -= len;
}
}
return true;
}
//获取数据,但不出队
bool cacheQueGet(CacheQue_st *que, uint8_t *buff, uint16_t len)
{
if(que == NULL || buff == NULL || len > cacheQueCurrentlen_get(que))
{
return false;
}
//队头在前
if(que->quefront < que->queRear)
{
memcpy(buff, &que->pArray[que->quefront], len);
}
else
{
if(len <= (que->maxlen - que->quefront))
{
memcpy(buff, &que->pArray[que->quefront], len);
}
else
{
memcpy(buff, &que->pArray[que->quefront], (que->maxlen - que->quefront));
memcpy(buff, que->pArray, (len - (que->maxlen - que->quefront)));
}
}
return true;
}
//从队头开始删除指定长度的数据
bool cacheQueDelete(CacheQue_st *que, uint16_t len)
{
if(que == NULL || len > cacheQueCurrentlen_get(que))
{
return false;
}
//队头在前
if(que->quefront < que->queRear)
{
memset(&que->pArray[que->quefront], 0, len);
que->quefront += len;
que->len -= len;
}
else
{
if(len <= (que->maxlen - que->quefront))
{
memset(&que->pArray[que->quefront], 0, len);
que->quefront += len;
que->len -= len;
}
else
{
memset(&que->pArray[que->quefront], 0, (que->maxlen - que->quefront));
memset(que->pArray, 0, (len - (que->maxlen - que->quefront)));
que->quefront = len - (que->maxlen - que->quefront);
que->len -= len;
}
}
return true;
}