网络收发之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 ...
随机推荐
- 搭建Hadoop集群 (三)
通过 搭建Hadoop集群 (二), 我们已经可以顺利运行自带的wordcount程序. 下面学习如何创建自己的Java应用, 放到Hadoop集群上运行, 并且可以通过debug来调试. 有多少种D ...
- 新视野OJ 2705 [SDOI2012]Longge的问题 (数论)
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2705 题解:求 sigma(gcd(i,n), 1<=i<=n<2^32) ...
- (转)C++笔记:面向对象编程基础
非常棒的总结 http://blog.csdn.net/liufei_learning/article/details/21312701 面向对象编程基础 面向对象编程基于三个基本概念: 数据抽象-类 ...
- 未能从程序集“System.ServiceModel, Version=3.0.0.0”中加载类型“System.ServiceModel.Activation.HttpModule” 的解决办法
未能从程序集“System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”中加载类型“ ...
- JS严格模式和非严格模式的区别
严格模式和非严格模式的区别 //f1.js 'use strice'; //整个js文件都是严格模式下执行的 var n = 1; var foo = function(){...}; //... v ...
- tpopela/vips_java
tpopela/vips_java Implementation of Vision Based Page Segmentation algorithm in Java
- android之获取应用中的图片资源_获取找你妹中的图片资源
一直不知道原来获取一个应用中的图片资源这么简单,刚才直接把apk解压,就得到了里面的一下文件,搜索一下就全部把图片资源找出来了,想要模仿应用或者自己不会ui的话,用现成的资源方便多了. 也没多少说的, ...
- Android Layout Binder(在线将XML中View find出来,生成java代码的工具)
废话不多说,这是地址:http://android.lineten.net/layout.php. 有图有真相,比如: 你的XML假如是这样: <?xml version="1.0&q ...
- OpenVPN多处理之-多队列TUN多线程
1.有一点不正确劲 在改动了那个TUN驱动后,我在想,为何我总是对一些驱动程序进行修修补补而从来不从应用程序找解决方式呢?我改动了那个TUN驱动,可是能保证我的改动对别的应用一样可用吗?难道TUN驱动 ...
- IOS开发之----协议与委托(Protocol and Delegate) 实例解析
1 协议: 协议,类似于Java或C#语言中的接口,它限制了实现类必须拥有哪些方法. 它是对对象行为的定义,也是对功能的规范. 在写示例之前我给大家说下@required和@optional这两个关键 ...