网络通信1:字节流的封装

网络通信1:字节流的封装在网络通讯中,数据在网络传输的格式常以字节流的形式进行,因此需要我们对字节流进行写入和读出的操作。在几乎其他所有语言中,网络数据的收发在利用类似

大家好,欢迎来到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

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信