大家好,欢迎来到IT知识分享网。
在网络通讯中,数据在网络传输的格式常以字节流的形式进行,因此需要我们对字节流进行写入和读出的操作。在几乎其他所有语言中,网络数据的收发在利用类似send(或write)和recv(或read)的方法时并没有明显的流处理。需要借助流才可以完成。数据流(data stream)是一组有序,有起点和终点的字节的数据序列。包括输入流和输出流。很多语言常将数据流分为输入流(InputStream)和输出流(OutputStream)两类。输入流只能读不能写,而输出流只能写不能读。通常程序中使用输入流读出数据,输出流写入数据,就好像数据流入到程序并从程序中流出。
为了提高数据的传输效率,通常使用缓冲流(Buffered Stream),即为一个流配有一个缓冲区(buffer),一个缓冲区就是专门用于传输数据的内存块。当向一个缓冲流写入数据时,系统不直接发送到外部设备,而是将数据发送到缓冲区。缓冲区自动记录数据,当缓冲区满时,系统将数据全部发送到相应的设备。当从一个缓冲流中读取数据时,系统实际是从缓冲区中读取数据。当缓冲区空时,系统就会从相关设备自动读取数据,并读取尽可能多的数据充满缓冲区。缓冲字节输入输出流,相对于基础的字节流有更高的效率,而效率更高的原理在于用空间换取时间。 也就是说使用缓冲流的时候,会先把一定的数据放到缓冲区,也就是内存中,然后read的时候直接从缓冲区读取,这样就减少了读写磁盘文件的次数,从而减少读写时间。
根据上面的原理能否实现字节流构造器。兼容输入流,输出流,缓冲流的功能。便于数据的组织和传输。同时兼容HTTP协议,TCP协议,UDP协议兼容的字节流。代码功能越独立越便于兼容。
C++实现网络数据流读取类:Gk8ByteMaker.h
//************************************************************** //@创建者:冰剑 //@创建时间:2008年3月8日 17时17分 //@功能描述①:网络数据流读取类:支持脚本中直接根据模板使用 //@功能描述②:注意服务器JAVA的高低位问题 //@功能描述③: //************************************************************** #ifndef __GK8NETBREADER_H__ #define __GK8NETBREADER_H__ #pragma once #include "Gk8Env.h" #include "Gk8PlatformDefine.h" #include "Gk8BaseObj.h" class Gk8ByteMaker:public Gk8BaseObj { DECLARE_TOSPP_MAP; protected: GK8_LPBYTE m_pBuf; //[数据缓存] GK8_INT m_nUseSize; //[使用大小] GK8_INT m_nBufSize; //[缓存分配大小] GK8_INT m_nReadPos; //[读取位置] public: Gk8ByteMaker():m_pBuf(NULL),m_nReadPos(0),m_nUseSize(0),m_nBufSize(0){}; ~Gk8ByteMaker(); static Gk8ByteMaker* Create(Gk8BaseObj* pSuperObj=NULL); //[属性操作] TOSPP_MEMBER_INT_DECLARE(m_nReadPos,m_nReadPos) inline GK8_INT TOSPPFUNC GetStreamSize()const{return m_nUseSize;}; GK8_LPBYTE WriteAlloc(GK8_INT nSize); //[读行为操作] GK8_BOOL Get(GK8_LPBYTE lpPtr,GK8_INT nLen)const; GK8_LPBYTE GetBuf(GK8_INT& nLen); inline GK8_LPBYTE GetBuf(){return m_pBuf;}; inline operator GK8_LPBYTE (){return GetBuf();}; GK8_VOID WriteBuf(GK8_LPCVOID lpPtr,GK8_INT nLen); GK8_VOID TOSPPFUNC WriteShort(GK8_INT nData); GK8_VOID TOSPPFUNC WriteInt(GK8_INT nData); GK8_VOID TOSPPFUNC WriteStr(GK8_LPCSTR lpStr); //[前面写入操作] GK8_VOID TOSPPFUNC WriteShortAt(GK8_INT nIndex,GK8_INT nData); GK8_VOID TOSPPFUNC WriteIntAt(GK8_INT nIndex,GK8_INT nData); GK8_VOID TOSPPFUNC WriteStrAt(GK8_INT nIndex,GK8_LPCSTR lpStr); //[读取操作] GK8_INT TOSPPFUNC ReadShort(); GK8_INT TOSPPFUNC ReadInt(); GK8_LPCSTR TOSPPFUNC ReadStr(); GK8_LONG TOSPPFUNC ReadLong(); //[其它行为操作] GK8_VOID ShiftTo(Gk8ByteMaker& iNetBReader); inline GK8_VOID SetReadPos(GK8_INT nReadPos){m_nReadPos=nReadPos;}; inline GK8_VOID TOSPPFUNC ClearStream(){m_nUseSize=0;}; GK8_VOID Pack(); GK8_VOID Destroy(); }; #endif
C++实现网络数据流读取类:Gk8ByteMaker.cpp
#include "Gk8ByteMaker.h" #include "Gk8MemSpy.h" #include "Gk8Str.h" #include "Gk8Helper.h" /////////////////////////////////////////////CLASS-TOLUA//////////////////////////////////////////////////// TOLUA_CLASS_COLLECT_FUNC(Gk8ByteMaker) BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,Create) if(!CheckToLuaFunParam(L,"Create",Gk8Var()<<ISUSERTABLE("Gk8ByteMaker"))) return 0; Gk8BaseObj* pSuperObj=NULL; if(IFUSERTYPE(2,Gk8BaseObj)) pSuperObj=TOLUAGETOBJ(Gk8BaseObj,2); Gk8ByteMaker* pByteMaker=Gk8ByteMaker::Create(pSuperObj); toluafix_pushusertype_ccobject(L,TOLUAOBJID(pByteMaker),TOLUALPLUAID(pByteMaker),(GK8_LPVOID)pByteMaker,"Gk8ByteMaker"); END_TOLUA_CLASS_FUNC BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,GetStreamSize) if(!CheckToLuaFunParam(L,"GetStreamSize",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNOOBJ)) return 0; tolua_pushnumber(L,(lua_Number)TOLUAGETOBJ(Gk8ByteMaker,1)->GetStreamSize()); END_TOLUA_CLASS_FUNC BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteShort) if(!CheckToLuaFunParam(L,"WriteShort",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNUMBER<<ISNOOBJ)) return 0; TOLUAGETOBJ(Gk8ByteMaker,1)->WriteShort(TOLUAGETINT(2)); END_TOLUA_CLASS_FUNC BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteInt) if(!CheckToLuaFunParam(L,"WriteInt",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNUMBER<<ISNOOBJ)) return 0; TOLUAGETOBJ(Gk8ByteMaker,1)->WriteInt(TOLUAGETINT(2)); END_TOLUA_CLASS_FUNC BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteStr) if(!CheckToLuaFunParam(L,"WriteStr",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISSTRING<<ISNOOBJ)) return 0; TOLUAGETOBJ(Gk8ByteMaker,1)->WriteStr(TOLUAGETSTRING(2)); END_TOLUA_CLASS_FUNC BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteShortAt) if(!CheckToLuaFunParam(L,"WriteShortAt",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNUMBER<<ISNUMBER<<ISNOOBJ)) return 0; TOLUAGETOBJ(Gk8ByteMaker,1)->WriteShortAt(TOLUAGETINT(2),TOLUAGETINT(3)); END_TOLUA_CLASS_FUNC BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteIntAt) if(!CheckToLuaFunParam(L,"WriteIntAt",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNUMBER<<ISNUMBER<<ISNOOBJ)) return 0; TOLUAGETOBJ(Gk8ByteMaker,1)->WriteIntAt(TOLUAGETINT(2),TOLUAGETINT(3)); END_TOLUA_CLASS_FUNC BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteStrAt) if(!CheckToLuaFunParam(L,"WriteStrAt",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISSTRING<<ISNUMBER<<ISNOOBJ)) return 0; TOLUAGETOBJ(Gk8ByteMaker,1)->WriteStrAt(TOLUAGETINT(2),TOLUAGETSTRING(3)); END_TOLUA_CLASS_FUNC BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,ReadShort) if(!CheckToLuaFunParam(L,"ReadShort",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNOOBJ)) return 0; tolua_pushnumber(L,(lua_Number)TOLUAGETOBJ(Gk8ByteMaker,1)->ReadShort()); END_TOLUA_CLASS_FUNC BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,ReadInt) if(!CheckToLuaFunParam(L,"ReadInt",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNOOBJ)) return 0; tolua_pushnumber(L,(lua_Number)TOLUAGETOBJ(Gk8ByteMaker,1)->ReadInt()); END_TOLUA_CLASS_FUNC BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,ReadStr) if(!CheckToLuaFunParam(L,"ReadStr",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNOOBJ)) return 0; tolua_pushstring(L,TOLUAGETOBJ(Gk8ByteMaker,1)->ReadStr()); END_TOLUA_CLASS_FUNC BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,ReadLong) if(!CheckToLuaFunParam(L,"ReadLong",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNOOBJ)) return 0; tolua_pushnumber(L,(lua_Number)TOLUAGETOBJ(Gk8ByteMaker,1)->ReadLong()); END_TOLUA_CLASS_FUNC BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,SetReadPos) if(!CheckToLuaFunParam(L,"SetReadPos",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNUMBER<<ISNOOBJ)) return 0; TOLUAGETOBJ(Gk8ByteMaker,1)->SetReadPos(TOLUAGETINT(2)); END_TOLUA_CLASS_FUNC BEGIN_TOLUA_CLASS_FUNC(Gk8ByteMaker,ClearStream) if(!CheckToLuaFunParam(L,"ClearStream",Gk8Var()<<ISUSERTYPE("Gk8ByteMaker")<<ISNOOBJ)) return 0; TOLUAGETOBJ(Gk8ByteMaker,1)->ClearStream(); END_TOLUA_CLASS_FUNC //[启动注册类的全部TOLUA函数] BEGIN_TOLUA_FUN_MAP(Gk8ByteMaker) TOLUA_CLASS(Gk8ByteMaker,"","[]","[]") TOLUA_CLASS_FUNC(Gk8ByteMaker,Create,"[Gk8ByteMaker* Create(pSuperObj=NULL)?创建对象]") TOLUA_CLASS_FUNC(Gk8ByteMaker,GetStreamSize,"[]") TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteShort,"[]") TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteInt,"[]") TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteStr,"[]") TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteShortAt,"[]") TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteIntAt,"[]") TOLUA_CLASS_FUNC(Gk8ByteMaker,WriteStrAt,"[]") TOLUA_CLASS_FUNC(Gk8ByteMaker,ReadShort,"[]") TOLUA_CLASS_FUNC(Gk8ByteMaker,ReadInt,"[]") TOLUA_CLASS_FUNC(Gk8ByteMaker,ReadStr,"[]") TOLUA_CLASS_FUNC(Gk8ByteMaker,ReadLong,"[]") TOLUA_CLASS_FUNC(Gk8ByteMaker,SetReadPos,"[]") TOLUA_CLASS_FUNC(Gk8ByteMaker,ClearStream,"[]") END_TOLUA_FUN_MAP /////////////////////////////////////////////CLASS-TOSPP//////////////////////////////////////////////////// BEGIN_TOSPP_MAP(Gk8ByteMaker,Gk8BaseObj) TOSPP_INT(Gk8ByteMaker,m_nReadPos,"m_nReadPos" ,"") TOSPP_FUNC(Gk8ByteMaker,GetStreamSize,'d'," ","GetStreamSize()") TOSPP_FUNC(Gk8ByteMaker,WriteShort,' ',"d","WriteShort(nData)") TOSPP_FUNC(Gk8ByteMaker,WriteInt,' ',"d","WriteInt(nData)") TOSPP_FUNC(Gk8ByteMaker,WriteStr,' ',"s","WriteStr(lpStr)") TOSPP_FUNC(Gk8ByteMaker,WriteShortAt,' ',"dd","WriteShortAt(nIndex,nData)") TOSPP_FUNC(Gk8ByteMaker,WriteIntAt,' ',"dd","WriteIntAt(nIndex,nData)") TOSPP_FUNC(Gk8ByteMaker,WriteStrAt,' ',"ds","WriteStrAt(nIndex,lpStr)") TOSPP_FUNC(Gk8ByteMaker,ReadShort,'d'," ","ReadShort()") TOSPP_FUNC(Gk8ByteMaker,ReadInt,'d'," ","ReadInt()") TOSPP_FUNC(Gk8ByteMaker,ReadStr,'s'," ","ReadStr()") TOSPP_FUNC(Gk8ByteMaker,ReadLong,'P'," ","ReadLong()") TOSPP_FUNC(Gk8ByteMaker,ClearStream,' '," ","ClearStream()") END_TOSPP_MAP() ///////////////////////////[网络二进制读取逻辑]/////////////////// Gk8ByteMaker::~Gk8ByteMaker() { if(m_pBuf) _Gk8Free(m_pBuf); } Gk8ByteMaker* Gk8ByteMaker::Create(Gk8BaseObj* pSuperObj) { Gk8ByteMaker* pByteMaker=new Gk8ByteMaker(); if(pSuperObj) pByteMaker->SetSuper(pSuperObj); return pByteMaker; } TOSPP_MEMBER_INT_FUN(Gk8ByteMaker,m_nReadPos,m_nReadPos) //[提前增加指定长度的内存块] GK8_LPBYTE Gk8ByteMaker::WriteAlloc(GK8_INT nSize) { if(nSize>=1) { if(nSize+m_nUseSize>=m_nBufSize) { GK8_UINT nNewSize; m_pBuf=(GK8_LPBYTE)_Gk8ReAlloc(m_pBuf,m_nUseSize+nSize+32,nNewSize); m_nBufSize=nNewSize; } m_nUseSize+=nSize; return m_pBuf+m_nUseSize-nSize; } return NULL; } //[获取指定长度的二进制数据] GK8_BOOL Gk8ByteMaker::Get(GK8_LPBYTE lpPtr,GK8_INT nLen)const { if(m_nUseSize>=nLen) memcpy(lpPtr,m_pBuf,nLen); return true; } //[获取数据的内存指针] GK8_LPBYTE Gk8ByteMaker::GetBuf(GK8_INT& nLen) { nLen=m_nUseSize; return m_pBuf; } //[增加指定长度的二进制数据] GK8_VOID Gk8ByteMaker::WriteBuf(GK8_LPCVOID lpPtr,GK8_INT nLen) { GK8_LPBYTE pMem=WriteAlloc(nLen); memcpy(pMem,lpPtr,nLen); } GK8_VOID Gk8ByteMaker::WriteShort(GK8_INT nData) { GK8_LPBYTE pMem=WriteAlloc(sizeof(GK8_WORD)); GK8_LPBYTE pDataMem=(GK8_LPBYTE)&nData; pMem[0]=pDataMem[1]; pMem[1]=pDataMem[0]; } GK8_VOID Gk8ByteMaker::WriteInt(GK8_INT nData) { GK8_LPBYTE pMem=WriteAlloc(sizeof(GK8_INT)); GK8_LPBYTE pDataMem=(GK8_LPBYTE)&nData; pMem[0]=pDataMem[3]; pMem[1]=pDataMem[2]; pMem[2]=pDataMem[1]; pMem[3]=pDataMem[0]; } GK8_VOID Gk8ByteMaker::WriteStr(GK8_LPCSTR lpStr) { Gk8Str iStr=lpStr; WriteShort(iStr.GetLength()); WriteBuf(iStr,iStr.GetLength()); } GK8_VOID Gk8ByteMaker::WriteShortAt(GK8_INT nIndex,GK8_INT nData) { GK8_INT nLen=sizeof(GK8_WORD); WriteAlloc(nLen); memmove(m_pBuf+nIndex+nLen,m_pBuf+nIndex,m_nUseSize-nLen-nIndex); GK8_LPBYTE pDataMem=(GK8_LPBYTE)&nData; m_pBuf[nIndex]=pDataMem[1]; m_pBuf[nIndex+1]=pDataMem[0]; } GK8_VOID Gk8ByteMaker::WriteIntAt(GK8_INT nIndex,GK8_INT nData) { GK8_INT nLen=sizeof(GK8_INT); WriteAlloc(nLen); memmove(m_pBuf+nIndex+nLen,m_pBuf+nIndex,m_nUseSize-nLen-nIndex); GK8_LPBYTE pDataMem=(GK8_LPBYTE)&nData; m_pBuf[nIndex]=pDataMem[3]; m_pBuf[nIndex+1]=pDataMem[2]; m_pBuf[nIndex+2]=pDataMem[1]; m_pBuf[nIndex+3]=pDataMem[0]; } GK8_VOID Gk8ByteMaker::WriteStrAt(GK8_INT nIndex,GK8_LPCSTR lpStr) { Gk8Str iStr=lpStr; GK8_INT nStrLen=iStr.GetLength(); GK8_INT nLen=sizeof(GK8_WORD)+nStrLen; WriteAlloc(nLen); memmove(m_pBuf+nIndex+nLen,m_pBuf+nIndex,m_nUseSize-nLen-nIndex); GK8_LPBYTE pDataMem=(GK8_LPBYTE)&nStrLen; m_pBuf[nIndex]=pDataMem[1]; m_pBuf[nIndex+1]=pDataMem[0]; memcpy(m_pBuf+nIndex+sizeof(GK8_WORD),iStr,nStrLen); } GK8_INT Gk8ByteMaker::ReadShort() { if(m_nReadPos>m_nUseSize-sizeof(GK8_WORD)) return NULL; GK8_INT nData; GK8_LPBYTE pDataMem=(GK8_LPBYTE)&nData; memset(pDataMem,0,sizeof(GK8_INT)); pDataMem[1]=m_pBuf[m_nReadPos]; pDataMem[0]=m_pBuf[m_nReadPos+1]; m_nReadPos+=sizeof(GK8_WORD); return nData; } GK8_INT Gk8ByteMaker::ReadInt() { if(m_nReadPos>m_nUseSize-sizeof(GK8_INT)) return 0; GK8_INT nData; GK8_LPBYTE pDataMem=(GK8_LPBYTE)&nData; memset(pDataMem,0,sizeof(GK8_INT)); pDataMem[3]=m_pBuf[m_nReadPos]; pDataMem[2]=m_pBuf[m_nReadPos+1]; pDataMem[1]=m_pBuf[m_nReadPos+2]; pDataMem[0]=m_pBuf[m_nReadPos+3]; m_nReadPos+=sizeof(GK8_INT); return nData; } GK8_LPCSTR Gk8ByteMaker::ReadStr() { if(m_nReadPos>m_nUseSize-sizeof(GK8_WORD)) return NULL; GK8_INT nLen; GK8_LPBYTE pDataMem=(GK8_LPBYTE)&nLen; memset(pDataMem,0,sizeof(GK8_INT)); pDataMem[1]=m_pBuf[m_nReadPos]; pDataMem[0]=m_pBuf[m_nReadPos+1]; m_nReadPos+=sizeof(GK8_WORD); Gk8Str iStr; iStr.SetStr((GK8_LPCSTR)(m_pBuf+m_nReadPos),nLen); m_nReadPos+=nLen; return iStr; } GK8_LONG Gk8ByteMaker::ReadLong() { return 0; } //[克隆到另外一个实体中] GK8_VOID Gk8ByteMaker::ShiftTo(Gk8ByteMaker& iBReader) { iBReader.Destroy(); iBReader.m_pBuf=m_pBuf; iBReader.m_nUseSize=m_nUseSize; iBReader.m_nBufSize=m_nBufSize; iBReader.m_nReadPos=m_nReadPos; m_pBuf=NULL; m_nBufSize=0; m_nUseSize=0; m_nReadPos=0; } //[整理数据:前面有内存已读取后面空余前移动] GK8_VOID Gk8ByteMaker::Pack() { if(m_nReadPos==m_nUseSize) { m_nUseSize=0; m_nReadPos=0; return; } memmove(m_pBuf,m_pBuf+m_nReadPos,m_nUseSize-m_nReadPos); m_nUseSize-=m_nReadPos; m_nReadPos=0; } //[销毁] GK8_VOID Gk8ByteMaker::Destroy() { if(m_pBuf) _Gk8Free(m_pBuf); m_pBuf=NULL; m_nUseSize=0; m_nBufSize=0; m_nReadPos=0; }
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/78245.html