网络收发之cycleBuf
#pragma once #include <iostream>
#include <string> class cyclebuffer
{
protected:
volatile int32_t m_nReadIndex;
volatile int32_t m_nWriteIndex;
volatile int32_t m_nDataSize; //有效数据大小
volatile int32_t m_nBufSize; //总buf大小
uint_8 *m_pBuf; public:
cyclebuffer(int nBufSize)
{
Reset();
m_pBuf = (uint8_t *)malloc(nBufSize);
m_nbufSize = nBufSize;
} virtual ~cyclebuffer()
{
if(m_pBuf != NULL)
{
free(m_pBuf);
m_pBuf = NULL;
}
} //剩余空间数
int32_t Space()
{
return m_nBufSize-m_nDataSize;
} //获取buf的总大小
int32_t Capatity()
{
return m_nBufSize;
} //获取有效数据长度
int32_t Size()
{
return m_nDataSize;
} //清空
void Reset()
{
m_nReadIndex = ;
m_nwriteIndex = ;
m_nDataSize = ;
} //增加nSize个字节
int32_t Grow(int32_t nSize)
{
if(nSize<=)
{
return ;
} uint8_t *pMem = (uint8_t *)malloc(nSize + m_nBufSize);
if(pMem == NULL)
{
return ;
} int32_t nWriteIndex = ;
//将旧内存中的数据拷贝到(增大的)新内存中
do
{
int32_t nReadBytes = Read(pMem + nWriteIndex, );
if(nReadBytes <= )
{
break;
}
nWriteIndex += nReadBytes;
}while(m_nDataSize > ); if(m_nDataSize > )
{
return -;
} //释放旧内存块
if(m_pBuf != NULL)
{
free(m_pBuf);
} m_pBuf = pMem;
m_nReadIndex = ;
m_nWriteIndex = nWriteIndex;
m_nDataSize = nWriteIndex;
m_nBufSize += nSize; return nSize;
} //写到写列表的头部---针对新数据
int32_t WriteToHead(const uint8_t *pBuf, int32_t nDataSize)
{
if(nDataSize < || pBuf == NULL)
{
return ;
} //空间不够
if(m_nDataSize + nDataSize > m_nBufsize)
{
if(Grow((m_nDataSize+nDataSize) - m_nDataSize) <= )
{
return ;
}
} if(m_nWriteIndex < m_nReadIndex)
{
memcpy(&m_pBuf[m_nReadIndex-nDataSize], pBuf, nDataSize);
m_nReadIndex -= nDataSize;
}
else if(m_nWriteIndex == m_nReadIndex)
{
return Write(pBuf, nDataSize);
}
else
{
int32_t nLeftDataSize = (nDataSize-m_nReadIndex<)?nDataSize:m_nReadIndex;
if(nLeftDataSize < nDataSize) //此时nLeftDataSize == m_nReadIndex,m_nReadIndex前面的空间不够
{
int32_t nTailDataSize = nDataSize - nLeftDataSize;
int32_t nWriteIndex = m_nBufSize - nTailDatasize;
memcpy(&m_pBuf[nWriteIndex], pBuf, nDataSize-nLeftDataSize); //从内存最后向前写
memcpy(&m_pBuf[], pBuf+nTailDataSize, nLeftDataSize);
m_nReadIndex = nWriteIndex;
}
else
{
if(m_nReadIndex-nDataSize < )
{
return ;
}
memcpy(&m_pBuf[m_nReadIndex-nDataSize], pBuf, nDataSize);
m_nReadIndex -= nDataSize;
}
} m_nDataSize += nDataSize;
return nDataSize;
} //写到列表的尾部
int32_t Write(const uint8_t *pBuf, int32_t nDataSize)
{
if(nDataSize <= || NULL == pBuf)
{
return ;
} if(nDataSize + m_nDataSize > m_nBufSize)
{
if(Grow((nDataSize+nBufSize)-m_nDataSize) <= )
{
return ;
}
} if(m_nWriteIndex < m_nReadIndex)
{
memcpy(&m_pBuf[m_nWriteIndex], pBuf, nDataSize);
m_nWriteIndex += nDataSize;
}
else
{
int32_t nLeftDataSize = m_nBufSize - m_nWriteIndex;
if(nLeftDataSize < nDataSize)
{
memcpy(&m_pBuf[m_nWriteIndex], pBuf, nLeftDataSize);
memcpy(&m_pBuf[], pBuf+nLeftDataSize, nDataSize-nLeftDataSize);
m_nwriteIndex = nDataSize - nLeftDataSize;
}
else
{
memcpy(&m_pBuf[m_nWriteIndex], pBuf, nDataSize);
m_nWriteIndex += nDataSize;
}
}
m_nDataSize += nDataSize;
return nDataSize;
} //读取 读列表的头部内存
int32_t Read(uint8_t *pBuf, const int32_t nWantSize)
{
if(nWantSize <= || NULL == pBuf)
{
return ;
} int32_t nDataSize = ((m_nDataSize < nWantSize)?m_nDataSize : nWantSize);
if(nDataSize<=)
{
return ;
} if(m_nReadIndex < m_nWriteIndex)
{
memcpy(pBuf, &m_pBuf[m_nReadIndex], nDataSize);
m_nReadIndex += nDataSize;
}
else
{
int32_t nLeftDataSize = m_nBufSize - m_nReadIndex;
if(nLeftDataSize < nDataSize)
{
memcpy(pBuf, &m_pBuf[m_nReadIndex], nLeftDataSize);
memcpy(pBuf+nLeftDataSize, &m_pBuf[], nDataSize-nLeftDataSize);
m_nReadIndex = nDataSize-nLeftDataSize;
}
else
{
memcpy(pBuf, &m_pBuf[m_nReadIndex], nDataSize);
m_nReadIndex += nDataSize;
}
}
m_nDataSize -= nDataSize;
return nDataSize;
} //读取数据但是不修改读索引
int32_t PeekRead(uint8_t *pBuf, const int32_t nWantSize)
{
if(nWantSize <= || pBuf == NULL)
{
return ;
} int32_t nDataSize = ((m_nDataSize < nWantSize) ? m_nDataSize : nWantSize);
if(m_nReadIndex < m_nWriteIndex)
{
memcpy(pBuf, &m_pBuf[m_nReadIndex], nDataSize);
}
else if(m_nReadIndex == m_nWriteIndex)
{
return ;
}
else
{
int32_t nLeftDataSize = m_nBufSize - m_nReadIndex;
if(nLeftDataSize < nDataSize)
{
memcpy(pBuf, &m_pBuf[m_nReadIndex], nLeftDataSize);
memcpy(pBuf+nLeftDataSize, &m_pBuf[], nDataSize-nLeftDataSize);
}
else
{
memcpy(pBuf, &m_pBuf[m_nReadIndex], nDataSize);
}
}
return nDataSize;
} };
网络收发之cycleBuf的更多相关文章
- kernel笔记——网络收发包流程
		
本文将介绍网络连接建立的过程.收发包流程,以及其中应用层.tcp层.ip层.设备层和驱动层各层发挥的作用. 应用层 对于使用socket进行网络连接的服务器端程序,我们会先调用socket函数创建一个 ...
 - Android 网络开发之WIFI
		
WIFI就是一种无线联网技术,常见的是使用无线路由器.那么在这个无线路由器的信号覆盖的范围内都可以采用WIFI连接的方式进行联网.如果无线路由器连接了一个ADSL线路或其他的联网线路,则又被称为&qu ...
 - iOS网络开发之AFNetworking
		
概述 AFNetworking是一个非常受欢迎的轻量级的iOS.Mac OS X网络通信类库.它建立在NSURLConnection.NSOperation以及其技术的基础上,有着精心设计的模块结构和 ...
 - Android网络开发之用tcpdump抓包
		
Android开发过程中,当涉及到网络通信的时候,有一些字段须要抓包获取.我之前由于SSDP设备发现的包头格式没有写对,经过抓包分析和标准包头对照发现了这个困扰我非常久的问题.总之,掌握在Androi ...
 - Android网络开发之OkHttp--基本用法实例化各个对象
		
1.实例化OkHttpClient对象,OkHttpClient包含了以下属性,以及set()和get()方法.但并没有包含具体的执行方法,详情见源码. //实例化OkHttpClent对象 priv ...
 - Android网络开发之OkHttp--基本用法POST
		
1.OkHttp框架使用了OkIo框架,不要忘记下OkIo.jar 2.通过POST访问网络,和通过GET访问网络基本相同,多了设置请求参数的过程.主要分为五步: (1).声明并实例化一个OkHttp ...
 - Android网络开发之OkHttp--基本用法GET
		
1.OkHttp框架使用了OkIo.jar包,不要忘记添加. 2.对于Request对象是如何实例化的,大家可以参考--java builder设计模式 http://www.cnblogs.com/ ...
 - Android网络开发之Volley--Volley自定义Request
		
1.自定义一个解析Json的Request,这里使用JackSon框架来解析Json.你也可以自定义一个解析XML的Request,或者使用FastSon来解析Json. 2.我们首先来看一下Stri ...
 - Android网络开发之Volley--Volley基本用法ImageRequest(三)
		
1.ImageRequest用法和StringRequest一样,主要分为3步: (1).实例化一个RequestQueue对象 (2).设置ImageRequest对象参数,并将ImageReque ...
 
随机推荐
- Labview学习之远程控制VI
			
Labview学习之远程控制VI 从LabVIEW 6.1开始,LabVIEW集成了Remote Panels技术,允许用户直接在客户端计算机上打开并操作位于服务器端计算机上的VI的前面 ...
 - 【LeetCode题意分析&解答】39. Combination Sum
			
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C wher ...
 - python 关于dict的一些总结
			
总结了一些关于字典的小技巧或者注意的地方. 使用zip创建字典 创建字典有以下三种方法 dict(a=1, b=2, c=2) dict([(a,1), (b,2), (c,3)]) dict({a: ...
 - VM 映像
			
 让我们一起欢呼吧!随着最近Microsoft Azure运行时的发布,我们非常高兴地宣布发布 OS映像的继承性产品:新 VM映像.等一下-有些人可能会觉得这听起来有点耳熟.没错,一个月前在旧金山 ...
 - [2013.9.8网络首发]导入Android4.2源码里的Gallery2和Camera模块至Eclipse全过程
			
[2013.9.8网络首发]导入Android4.2源码里的Gallery2和Camera模块至Eclipse全过程 google的android自带的apps写的是相当牛逼的,将其导入到ecli ...
 - 自己动手写RTP服务器——传输所有格式的视频
			
上一篇文章我们介绍了如何用一个简单的UDP socket搭建一个RTP服务器.我把这份80行的代码呈现到客户面前的时候,就有人不满意了. 还有人在参考的时候会问:“楼主你的TS格式的文件是哪里来的?应 ...
 - 《windows程序设计》学习_2.1:初识消息
			
#include <windows.h> //#define WM_MYMSG (WM_USER +100) LRESULT CALLBACK WndProc(HWND,UINT,WPAR ...
 - Win7搭建Django开发环境
			
1.官网下载并安装python 2.7.5 2.配置python 环境变量 在Path中加入python安装目录: PATH=PATH;c:\python26 在PATHEXT中加入以下变量,可以直接 ...
 - android解决内存溢出的问题(没有从根本上解决)
			
Android游戏虚拟机算法JNI 尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,因为这些函数在完 ...
 - c++中string::function集合
			
string append() 1.直接添加另一个完整的字符串: str1.append(str2); 2.添加另一个字符串的某一段字串: str1.append(str2, 11, 7); ...