网络收发之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 ...
随机推荐
- YII与Ace Admin 的集成
目录 一. 前言... 1 二.为什么要使用YII+ace. 1 三.新建YII模块... 1 四.如何修改模板... 3 五.注意的地方... 4 六.整合的不足之处... 4 一. 前言 yii- ...
- 一周学会Mootools 1.4中文教程:(4)类型
Mootools的类型主要包含下边几部分:String:字符串;Number:数字;Array:数组;Object:对象;Json:;Cookie:. 这也是我们今天的讲述重点.每一种数据类型Mt都为 ...
- RequireJS 和 SeaJS
RequireJS SeaJS CMD规范 CommonJS的规范: 根据CommonJS规范,一个单独的文件就是一个模块.加载模块使用require方法,该方法读取一个文件并执行,最后返回文件内部的 ...
- .NET(C#):觉察XML反序列化中的未知节点
原文 www.cnblogs.com/mgen/archive/2011/12/12/2284554.html 众所周知XML是可以扩展的,XML的元素可以靠名称识别而不是只按照未知识别.在 XML反 ...
- 转:CSS Overflow 属性
原文:CSS Overflow 属性译自:The CSS Overflow Property版权所有,转载请注明出处,多谢!! 根据CSS的盒模型概念,页面中的每个元素,都是一个矩形的盒子.这些盒子的 ...
- 关于Struts2的碎碎念
一:安全,还是安全 我入行比较晚,那会Spring MVC什么的都很流行了,一直觉得struts2作为一个Web MVC框架实在太笨重了点.所以虽然之前一直在用,但是其实没有真正研究过. 今天公司又遇 ...
- uva 10548 - Find the Right Changes(拓展欧几里得)
题目链接:uva 10548 - Find the Right Changes 题目大意:给定A,B,C,求x,y,使得xA+yB=C,求有多少种解. 解题思路:拓展欧几里得,保证x,y均大于等于0, ...
- chrome扩展小试
chorme 扩展 小试 官方文档 http://developer.chrome.com/extensions 非官方中文文档 http://docs.lmk123.com/getstarted.h ...
- Random类短时间大量随机重复的问题
先声明一下,我是在那篇文章上看到的解决方法: http://dl.download.csdn.net/down10/20141103/4b173214e41ff3207305c2470524b0f3. ...
- Maven+SpringMVC+MyBatis 上传图片
上传文件我一直都觉得很难,好吧,所有涉及文件操作的我都觉得不容易.然后今天尝试了从网页上传图片保存到服务器.这个例子的前提是搭建好了服务器端框架:Maven+Spring MVC+MyBatis.当然 ...