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这个文件的申请(因为发送给不同客户的)