一个简单的用来接收包缓存的buffer,在可能有连续多个包的时候,不用每次移动缓存,只需要移动index位置,等到快用完后,再将数据移到指针起始位置
RecvBuffer.h
#ifndef RECV_BUFFER_H
#define RECV_BUFFER_H
#include <stdio.h>
#include <iostream>
//
//
//
/// A buffer class modeled after org.jboss.netty.buffer.ChannelBuffer
///
/// @code 已读内容 实际还剩下的内容 剩余空间
/// +-------------------+------------------+------------------+
/// | prependable bytes | readable bytes | writable bytes |
/// | | (CONTENT) | |
/// +-------------------+------------------+------------------+
/// | | | |
/// 0 <= readerIndex <= writerIndex <= size
/// @endcode
#define MIN_FREE_SIZE 4096
class CRecvBuffer
{
public:
CRecvBuffer(size_t iSize = 65535);
~CRecvBuffer();
//获取可写的位置
char* GetWritePos();
//获取可读的位置
char* GetReadPos();
void ReMoveBuff()
{
memmove(p, p+readerIndex, recvSize);
readerIndex = 0;
writerIndex = recvSize;
}
size_t GetFreeSize()
{
size_t iFreeSize = bufferSize - readerIndex - recvSize;
//剩余空间不足4096,或者不足总大小1/10时,将数据移到开头
if(iFreeSize < MIN_FREE_SIZE || iFreeSize <bufferSize/10)
{
ReMoveBuff();
}
return bufferSize - readerIndex - recvSize;
}
size_t GetRecvSize()
{
return recvSize;
}
void AddRecvSize(size_t iSize)
{
recvSize += iSize;
writerIndex = readerIndex + recvSize;
}
void DecRecvSize(size_t iSize)
{
recvSize -= iSize;
readerIndex += iSize;
if(readerIndex == writerIndex || recvSize == 0)//刚好读完了
{
readerIndex = 0;
writerIndex = 0;
}
}
private:
char* p;
size_t readerIndex; //已读的最后位置
size_t writerIndex; //已写的最后位置
size_t recvSize; //剩余的数据的大小
size_t freeSize; //写位置后面还有空余的位置大小
size_t bufferSize; //buffer总大小
};
#endif
RecvBuffer.cpp
#include "RecvBuffer.h"
CRecvBuffer::CRecvBuffer(size_t iSize):p(NULL),readerIndex(0), writerIndex(0),recvSize(0),freeSize(0),bufferSize(iSize)
{
if(iSize)
{
p = new char[iSize];
memset(p, 0, iSize);
}
}
CRecvBuffer::~CRecvBuffer()
{
if(p)
{
delete[] p;
p = NULL;
}
}
char* CRecvBuffer::GetWritePos()
{
if(!p) return NULL;
return p+writerIndex;
}
char* CRecvBuffer::GetReadPos()
{
if(!p) return NULL;
return p+readerIndex;
}