游戏服务端之间内部通讯数的据包解析
来源:互联网 发布:淘宝开店身份证照片图 编辑:程序博客网 时间:2024/05/20 05:46
DB的包发送结构:
CDataPacket& retPack = allocProtoPacket(dcQuery);
(1):CDataPacket& CLogicDBReqestHandler::allocProtoPacket(const jxSrvDef::INTERSRVCMD nCmd)
{
return m_pHost->AllocDataPacket(nCmd);
}
(2):CDataPacket& CDBDataClient::AllocDataPacket(const jxSrvDef::INTERSRVCMD nCmd)
{
return allocProtoPacket(nCmd);
}
(3):CDataPacket& CCustomJXServerClientSocket::allocProtoPacket(const jxSrvDef::INTERSRVCMD nCmd)
{
CDataPacket &Packet = allocSendPacket();
PDATAHEADER pPackHdr;
//预留通信数据头空间
Packet.setLength(sizeof(*pPackHdr));
Packet.setPosition(sizeof(*pPackHdr));
pPackHdr = (PDATAHEADER)Packet.getMemoryPtr();
pPackHdr->tag = DEFAULT_TAG_VALUE;
//写入通信消息号
Packet << nCmd;
return Packet;
}
(4): inline CDataPacket& allocSendPacket()
{
CDataPacket *pPacket;
allocSendPacketList(*((CBaseList<CDataPacket*>*)NULL), 0, &pPacket);
pPacket->setLength(0);
return *pPacket;
}
(5):VOID CSendPacketPool::allocSendPacketList(CBaseList<CDataPacket*>& packetList, INT_PTR nAllocCount, CDataPacket **ppSingleAlloc)
{
static const INT_PTR PacketBlockCountAlgin = 512;
INT_PTR nCount, nRemainCount;
m_FreeSendPackList.lock();
nCount = m_FreeSendPackList.count();
//从当前空闲列表中拷贝
if ( nCount > 0 && nAllocCount > 0 )
{
nRemainCount = nCount - nAllocCount;
if ( nRemainCount > 0 )
{
packetList.addArray(&m_FreeSendPackList[nRemainCount], nAllocCount);
m_FreeSendPackList.trunc(nRemainCount);
nAllocCount = 0;
}
else
{
//添加现有的
packetList.addArray(m_FreeSendPackList, nCount);
m_FreeSendPackList.trunc(0);
nCount = 0;
}
nCount = m_FreeSendPackList.count();
}
if ( ppSingleAlloc && nCount > 0 )
{
nCount--;
*ppSingleAlloc = m_FreeSendPackList[nCount];
m_FreeSendPackList.trunc(nCount);
ppSingleAlloc = NULL;//将参数置空,以便后续的操作不需要多申请一个
}
//仍不足需求数量则继续申请
if ( ppSingleAlloc || nAllocCount > 0 )
{
//申请数据包对象内存块
INT_PTR i, nNewCount = __max(PacketBlockCountAlgin, nAllocCount);
//如果还需要申请一个单独的数据包,则增加需求数量
if ( ppSingleAlloc ) nNewCount ++;
nNewCount = (nNewCount + PacketBlockCountAlgin) & (~(PacketBlockCountAlgin - 1));
CDataPacket *pPacket = (CDataPacket*)m_Allocator.AllocBuffer(sizeof(*pPacket) * nNewCount);
//讲数据包集的内存块添加到数据内存头列表中
//m_SendPacketMemList.add(pPacket);
//如果空闲发送送数据列表的剩余空间不足以放下新申请的数据包,则增长空闲发送数据包列表的保留长度
if ( m_FreeSendPackList.maxCount() < nCount + nNewCount )
m_FreeSendPackList.reserve(nCount + nNewCount);
//循环调用构造函数
for (i=0; i<nNewCount; ++i)
{
new(pPacket)CDataPacket(&m_Allocator);
m_FreeSendPackList[nCount] = pPacket;//将数据包保存到空闲发送送数据列表
pPacket++;
nCount++;
}
//将剩余申请的数据包拷贝到申请列表中
if ( nAllocCount > 0 )
{
nCount -= nAllocCount;
packetList.addArray(&m_FreeSendPackList[nCount], nAllocCount);
m_FreeSendPackList.trunc(nCount);
}
//需要申请一个单独的数据包
if ( ppSingleAlloc )
{
nCount--;
*ppSingleAlloc = m_FreeSendPackList[nCount];
m_FreeSendPackList.trunc(nCount);
}
}
m_FreeSendPackList.unlock();
}
引擎的DB发送结构:
CDataPacket& DataPacket = m_pEntity->AllocPacket(AP);
(1):#ifdef _DEBUG
CDataPacket& CActor::_AllocPacket(CActorPacket &pack, LPCSTR file, INT_PTR line)
#else
CDataPacket& CActor::AllocPacket(CActorPacket &pack)
#endif
{
#ifdef _DEBUG
Assert(GetCurrentThreadId() == GetLogicServer()->GetLogicEngine()->getThreadId());
Assert(FALSE == InterlockedCompareExchange(&g_boPacketAlreadyAlloced, TRUE, FALSE));
g_sPacketAllocFile = file;
g_nPacketAllocLine = line;
#endif
CLogicGate* logicgate = (CLogicGate*)GetLogicServer()->GetGateManager()->getGate(m_nGateID);
//CDataPacket* pSendToGatePacket = NULL;
pack.packet = logicgate->GetSendToGatePacket();
//Assert(&pack.packet);
//OutputMsg(rmTip,"AllocPacket =%d",pack.packet->getOffsetPtr());
if(!m_isInited)
{
#ifdef _DEBUG
OutputMsg(rmError,"AllocData when actor not inited,file=%s,line=%d",file,(int)line);
#else
OutputMsg(rmError,"AllocData when actor not inited");
#endif
//如果是调试版本直接挂掉服务器
}
pack.packet->reserve(pack.packet->getPosition()+sizeof(GATEMSGHDR));
PGATEMSGHDR pHdr = (PGATEMSGHDR)pack.packet->getOffsetPtr();//保留协议头部分
pack.nHdrPos = pack.packet->getPosition();
pHdr->dwGateCode = RUNGATECODE;
pHdr->nSocket = m_nUserSocket;
pHdr->wSessionIdx= (WORD)m_nGateSessionIndex;
pHdr->wIdent = GM_DATA;
pHdr->wServerIdx = m_nServerSessionIndex;
pHdr->nDataSize = 0;
pHdr->wTemp = RUNTEMPCODE;
pHdr->tickCount = _getTickCount();
pack.packet->adjustOffset(sizeof(GATEMSGHDR));
pack.pActor = this;
return *pack.packet;
}
会话的发送结构:
CDataPacket &out = allocProtoPacket(sCheckPasswdResult);
(1):直接引用基类函数:CDataPacket& CCustomJXServerClientSocket::allocProtoPacket(const jxSrvDef::INTERSRVCMD nCmd)
{
CDataPacket &Packet = allocSendPacket();
PDATAHEADER pPackHdr;
//预留通信数据头空间
Packet.setLength(sizeof(*pPackHdr));
Packet.setPosition(sizeof(*pPackHdr));
pPackHdr = (PDATAHEADER)Packet.getMemoryPtr();
pPackHdr->tag = DEFAULT_TAG_VALUE;
//写入通信消息号
Packet << nCmd;
return Packet;
}
(2):VOID CCustomJXServerClientSocket::flushProtoPacket(CDataPacket& packet)
{
PDATAHEADER pPackHdr = (PDATAHEADER)packet.getMemoryPtr();
//计算并向协议头中写入通信数据长度
INT_PTR nDataSize = packet.getLength() - sizeof(*pPackHdr);
if(nDataSize >65535)
{
WORD wHead= *(WORD*)((char*)packet.getMemoryPtr() + sizeof(*pPackHdr));
OutputMsg(rmError,"严重错误CCustomJXServerClientSocket::flushProtoPacket 数据长度%d过长,head=%d",(int)nDataSize,(int)wHead);
}
pPackHdr->len = (WORD)nDataSize;
flushSendPacket(packet);
}
总结:通过内存池申请包,发送包放到缓冲列表,线程从缓冲列表拿到数据进行转发。再进行解析,获取数据.数据获取
完毕以后还要返回给内存池,
通用包结构:
其它发给引擎的话一般用到的是:CustomJXServerClientSocket.cpp这个文件的申请
引擎发给引擎的话一般用到的是:CustomJXClientSocket.cpp这个文件的申请(因为发送给不同客户的)
武艺lib库中最基础数据的申请
阅读全文
0 0
- 游戏服务端之间内部通讯数的据包解析
- 游戏服务端通讯框架实现
- java TCP客户端与服务端之间的通讯
- 新手学习-Tcp的服务端与客户端之间进行通讯
- 木马客户端与服务端隐蔽通讯解析
- 两个APP之间的通讯(客户端调用服务端里的音乐播放)
- 实例解析C++/CLI程序进程之间的通讯
- mysql 协议的服务端握手包及对其解析
- UDP的内部通讯纠结-
- 进程之间的通讯
- ViewModel之间的通讯
- 应用之间的通讯
- fragment之间的通讯
- zebra之间的通讯
- 通讯包的设计
- web服务端和游戏服务端的区别
- 足迹二:Android客户端与PC服务端之间的SOCKET通讯实现登陆功能(客户端 仅供学习)
- android_json解析的服务端
- 判断文件是否存在,不存在则新建
- spring项目开发小记2
- 博客flag日志
- 使用DownloadManager进行版本更新(兼容7.0)
- 驼峰式命名的字符串与数据库字段下划线大写方式的转换
- 游戏服务端之间内部通讯数的据包解析
- 111. Minimum Depth of Binary Tree
- java-抽象类
- mysql创建删除用户
- findContours
- 访问家庭内网资源
- [译] TensorFlow 白皮书
- CSS3中:nth-child和:nth-of-type的区别深入理解
- WiFi-ESP8266入门开发(四)-设置软热点