This commit is contained in:
aixianling
2025-01-09 17:45:40 +08:00
commit 5c9f1dae4a
3482 changed files with 1146531 additions and 0 deletions

View File

@@ -0,0 +1,139 @@
#include <stdlib.h>
#include <stdio.h>
#ifdef WIN32
#include <tchar.h>
#include <Windows.h>
#endif
#include <_ast.h>
#include <_memchk.h>
#include <Thread.h>
#include <Tick.h>
#include <Lock.h>
#include <QueueList.h>
#include <CustomSocket.h>
#include "ShareUtil.h"
#include "BufferAllocator.h"
#include "GateProto.h"
#include "AppItnMsg.h"
#include "DataPacket.hpp"
#include "SendPackPool.h"
#include "CustomWorkSocket.h"
#include "CustomServerClientSocket.h"
#include "CustomServerClientSocketEx.h"
#include "CustomServerSocket.h"
#include "CustomServerGate.h"
#include "CustomGateManager.h"
CCustomGateManager::CCustomGateManager()
{
ZeroMemory(m_GateList, sizeof(m_GateList));
SetSingleLoopCount(8);
}
CCustomGateManager::~CCustomGateManager()
{
Stop();
}
BOOL CCustomGateManager::Startup()
{
//初始化网关列表
for (INT_PTR i=0; i<ArrayCount(m_GateList); ++i)
{
m_GateList[i]->m_nGateIndex = i;
}
return Inherited::Startup();
}
VOID CCustomGateManager::Stop()
{
Inherited::Stop();
}
VOID CCustomGateManager::PostCloseGateUser(SOCKET nUserSocket)
{
INT_PTR i;
//向每个已经连接的网关对象发送关闭用户的消息
for ( i=0; i<ArrayCount(m_GateList); ++i )
{
if ( !m_GateList[i]->connected() )
{
m_GateList[i]->PostCloseUser(nUserSocket);
}
}
}
VOID CCustomGateManager::PostCloseGateUserByGlobalSessionId(int nSessionId)
{
INT_PTR i;
//向每个已经连接的网关对象发送关闭用户的消息
for ( i=0; i<ArrayCount(m_GateList); ++i )
{
if ( m_GateList[i]->connected() )
{
m_GateList[i]->PostCloseUserByGlobalSessionId(nSessionId);
}
}
}
VOID CCustomGateManager::PostKickGateUserByGlobalUser(int nSessionId)
{
INT_PTR i;
//向每个已经连接的网关对象发送关闭用户的消息
for ( i=0; i<ArrayCount(m_GateList); ++i )
{
if ( m_GateList[i]->connected() )
{
m_GateList[i]->PostKickUserByGlobalSessionId(nSessionId);
}
}
}
CCustomServerClientSocket* CCustomGateManager::CreateClientSocket(SOCKET nSocket, PSOCKADDR_IN pAddrIn)
{
//从预初始的网关列表中返回一个没有使用的网关连接对象
INT_PTR i;
for ( i=0; i<ArrayCount(m_GateList); ++i )
{
if ( !m_GateList[i]->connected() )
{
OutputMsg( rmTip, _T("接受网关客户端连接!") );
m_GateList[i]->SetClientSocket(nSocket, pAddrIn);
m_GateList[i]->ClearSendBuffers();
m_GateList[i]->StartWork();
return m_GateList[i];
}
}
return NULL;
}
VOID CCustomGateManager::DestroyClientSocket(CCustomServerClientSocket *pClientSocket)
{
//什么都不处理
((CCustomServerGate *)pClientSocket)->StopWork();
}
VOID CCustomGateManager::DispatchInternalMessage(UINT uMsg, UINT64 uParam1, UINT64 uParam2, UINT64 uParam3,UINT64 uParam4)
{
//按全局会话ID查询网关用户是否存在Param1=全局会话ID
if (uMsg == SGIM_QUERY_GSID_USER_EXISTS)
{
INT_PTR i;
int nSessionId = (int)uParam1;
BOOL boExists = FALSE;
for ( i=0; i<ArrayCount(m_GateList); ++i )
{
if ( m_GateList[i]->connected() )
{
if ( m_GateList[i]->UserExistsOfGlobalSessionId(nSessionId, NULL) )
{
boExists = TRUE;
break;
}
}
}
OnResultGateUserExists(nSessionId, boExists);
}
else Inherited::DispatchInternalMessage(uMsg, uParam1, uParam2, uParam3,uParam4);
}

View File

@@ -0,0 +1,160 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
#include <tchar.h>
#include <Windows.h>
#endif
#include <_ast.h>
#include <_memchk.h>
#include <Thread.h>
#include <CustomSocket.h>
#include <Tick.h>
#include <Lock.h>
#include <QueueList.h>
#include "ShareUtil.h"
#include "BufferAllocator.h"
#include "AppItnMsg.h"
#include "DataPacket.hpp"
#include "SendPackPool.h"
#include "CustomWorkSocket.h"
#include "CustomClientSocket.h"
#include "ServerDef.h"
#include "CommonDef.h"
//#include "../encrypt/CRC.h"
//#include "../encrypt/Encrypt.h"
//#include "../dataProcess/NetworkDataHandler.h"
#include "CustomJXClientSocket.h"
using namespace jxSrvDef;
CDataPacket& CCustomJXClientSocket::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;
}
VOID CCustomJXClientSocket::SendKeepAlive()
{
CDataPacket& packet = allocProtoPacket(0);
flushProtoPacket(packet);
}
VOID CCustomJXClientSocket::flushProtoPacket(CDataPacket& packet)
{
PDATAHEADER pPackHdr = (PDATAHEADER)packet.getMemoryPtr();
//计算并向协议头中写入通信数据长度
// printf("packet.getLength:%d, *pPackHdr:%d\n",packet.getLength(), sizeof(*pPackHdr));
// pPackHdr->len = (WORD)packet.getLength() - sizeof(*pPackHdr);
pPackHdr->len = packet.getLength() - sizeof(*pPackHdr);
flushSendPacket(packet);
}
int CCustomJXClientSocket::getLocalServerIndex()
{
return 0;
}
VOID CCustomJXClientSocket::SendRegisteClient()
{
SERVER_REGDATA regData;
ZeroMemory( &regData, sizeof(regData) );
regData.GameType = SERVER_REGDATA::GT_JianXiaoJiangHu;
regData.ServerType = getLocalServerType();
regData.ServerIndex = getLocalServerIndex();
_asncpytA( regData.ServerName, getLocalServerName() );
//OutputMsg( rmTip, _T("发送注册包,name=%s,ServerType=%dServerIndex=%d"),
// getLocalServerName(), getLocalServerType(),getServerIndex());
send(&regData, sizeof(regData));
}
VOID CCustomJXClientSocket::ProcessRecvBuffers(PDATABUFFER pDataBuffer)
{
//如果连接已断开则丢弃所有数据
if ( !connected() )
{
Inherited::ProcessRecvBuffers(pDataBuffer);
SwapRecvProcessBuffers();
return;
}
if ( pDataBuffer->nOffset <= 0 )
{
SwapRecvProcessBuffers();
return;
}
jxSrvDef::INTERSRVCMD nCmd;
INT_PTR dwRemainSize;
PDATAHEADER pPackHdr;
char* pDataEnd = pDataBuffer->pBuffer + pDataBuffer->nOffset;
while ( TRUE )
{
dwRemainSize = (INT_PTR)(pDataEnd - pDataBuffer->pPointer);
//如果缓冲区中的剩余长度小于通信协议头的长度,则交换缓冲并在以后继续进行处理
if ( dwRemainSize < sizeof(*pPackHdr) )
{
SwapRecvProcessBuffers();
break;
}
pPackHdr = (PDATAHEADER)pDataBuffer->pPointer;
//检查包头标志是否有效,如果包头标志无效则需要遍历数据包查找包头
if ( pPackHdr->tag != DEFAULT_TAG_VALUE )
{
char* sCurPtr = pDataBuffer->pPointer;
do
{
pDataBuffer->pPointer++;
pPackHdr = (PDATAHEADER)pDataBuffer->pPointer;
//找到包头标记则终止查找
if ( pPackHdr->tag == DEFAULT_TAG_VALUE )
break;
}
while (pDataBuffer->pPointer < pDataEnd - 1);
//如果无法查找到包头,则保留接收缓冲末尾的最后一个字符并交换接收/处理缓冲以便下次继续连接新接收的数据后重新查找包头
if ( pPackHdr->tag != DEFAULT_TAG_VALUE )
{
SwapRecvProcessBuffers();
//找不到协议头标志,输出错误消息
OutputMsg(rmError, _T("%s recv invalid server data, proto header can not be found"), GetClientName());
break;
}
//输出找到包头的消息
OutputMsg(rmError, _T("%s recv invalid server data, proto header refound after %d bytes"),
GetClientName(), (int)(pDataBuffer->pPointer - sCurPtr));
}
//如果处理接收数据的缓冲中的剩余数据长度不足协议头中的数据长度,则交换缓冲并在下次继续处理
dwRemainSize -= sizeof(*pPackHdr);
if ( pPackHdr->len > dwRemainSize )
{
SwapRecvProcessBuffers();
break;
}
//将缓冲读取指针调整到下一个通信数据包的位置
pDataBuffer->pPointer += sizeof(*pPackHdr) + pPackHdr->len;
if ( pPackHdr->len >= sizeof(nCmd) )
{
//将通信数据段保存在packet中
CDataPacketReader packet(pPackHdr + 1, pPackHdr->len);
//分派数据包处理
packet >> nCmd;
OnDispatchRecvPacket(nCmd, packet);
}
else
{
OutputMsg(rmError, _T("%s recv invalid server packet, packet size to few(%d)"),
GetClientName(), pPackHdr->len);
}
}
}

View File

@@ -0,0 +1,186 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
#include <tchar.h>
#include <Windows.h>
#endif
#include <_ast.h>
#include <_memchk.h>
#include <Thread.h>
#include <CustomSocket.h>
#include <Tick.h>
#include <Lock.h>
#include <QueueList.h>
#include "ShareUtil.h"
#include "BufferAllocator.h"
#include "AppItnMsg.h"
#include "DataPacket.hpp"
#include "SendPackPool.h"
#include "CustomWorkSocket.h"
#include "CustomClientSocket.h"
#include "CustomServerClientSocket.h"
#include "ServerDef.h"
#include "CommonDef.h"
//#include "../encrypt/CRC.h"
//#include "../encrypt/Encrypt.h"
//#include "../dataProcess/NetworkDataHandler.h"
#include "CustomJXServerClientSocket.h"
using namespace jxSrvDef;
CCustomJXServerClientSocket::CCustomJXServerClientSocket()
:Inherited()
{
m_boRegisted = false;
m_nClientSrvIdx = 0;
m_sClientName[0] = 0;
m_eClientType = InvalidServer;
}
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;
}
VOID CCustomJXServerClientSocket::SendKeepAlive()
{
CDataPacket& packet = allocProtoPacket(0);
flushProtoPacket(packet);
}
VOID CCustomJXServerClientSocket::flushProtoPacket(CDataPacket& packet)
{
PDATAHEADER pPackHdr = (PDATAHEADER)packet.getMemoryPtr();
//计算并向协议头中写入通信数据长度
INT_PTR nDataSize = packet.getLength() - sizeof(*pPackHdr);
if(nDataSize >INT_MAX)
{
WORD wHead= *(WORD*)((char*)packet.getMemoryPtr() + sizeof(*pPackHdr));
OutputMsg(rmError,"严重错误CCustomJXServerClientSocket::flushProtoPacket 数据长度%d过长,head=%d",(int)nDataSize,(int)wHead);
}
pPackHdr->len = nDataSize;
flushSendPacket(packet);
}
VOID CCustomJXServerClientSocket::ProcessRecvBuffers(PDATABUFFER pDataBuffer)
{
//如果连接已断开则丢弃所有数据
if ( !connected() )
{
Inherited::ProcessRecvBuffers(pDataBuffer);
SwapRecvProcessBuffers();
return;
}
if ( pDataBuffer->nOffset <= 0 )
{
SwapRecvProcessBuffers();
return;
}
//如果客户端尚未注册则处理注册数据包
if ( !m_boRegisted )
{
PSERVER_REGDATA pRegData;
if ( pDataBuffer->nOffset >= sizeof(*pRegData) )
{
pRegData = (PSERVER_REGDATA)pDataBuffer->pBuffer;
if ( !OnValidateRegData(pRegData) )
{
close();
SwapRecvProcessBuffers();
return;
}
m_boRegisted = true;
m_eClientType = (SERVERTYPE)pRegData->ServerType;
m_nClientSrvIdx = pRegData->ServerIndex;
_asncpytA(m_sClientName, pRegData->ServerName);
pDataBuffer->pPointer += sizeof(*pRegData);
OnRegDataValidated();
OutputMsg(rmTip, _T("%s client (%s:%d) registe success (%s)"), getServerTypeName(m_eClientType),
GetRemoteHost(), GetRemotePort(), m_sClientName);
}
}
jxSrvDef::INTERSRVCMD nCmd;
INT_PTR dwRemainSize;
PDATAHEADER pPackHdr;
char* pDataEnd = pDataBuffer->pBuffer + pDataBuffer->nOffset;
while ( TRUE )
{
dwRemainSize = (INT_PTR)(pDataEnd - pDataBuffer->pPointer);
//如果缓冲区中的剩余长度小于通信协议头的长度,则交换缓冲并在以后继续进行处理
if ( dwRemainSize < sizeof(*pPackHdr) )
{
SwapRecvProcessBuffers();
break;
}
pPackHdr = (PDATAHEADER)pDataBuffer->pPointer;
//检查包头标志是否有效,如果包头标志无效则需要遍历数据包查找包头
if ( pPackHdr->tag != DEFAULT_TAG_VALUE )
{
char* sCurPtr = pDataBuffer->pPointer;
do
{
pDataBuffer->pPointer++;
pPackHdr = (PDATAHEADER)pDataBuffer->pPointer;
//找到包头标记则终止查找
if ( pPackHdr->tag == DEFAULT_TAG_VALUE )
break;
}
while (pDataBuffer->pPointer < pDataEnd - 1);
//如果无法查找到包头,则保留接收缓冲末尾的最后一个字符并交换接收/处理缓冲以便下次继续连接新接收的数据后重新查找包头
if ( pPackHdr->tag != DEFAULT_TAG_VALUE )
{
SwapRecvProcessBuffers();
//找不到协议头标志,输出错误消息
OutputMsg(rmError, _T("%s recv invalid server data, proto header can not be found"), getClientName());
break;
}
//输出找到包头的消息
OutputMsg(rmError, _T("%s recv invalid server data, proto header refound after %d bytes"),
getClientName(), (int)(pDataBuffer->pPointer - sCurPtr));
}
//如果处理接收数据的缓冲中的剩余数据长度不足协议头中的数据长度,则交换缓冲并在下次继续处理
dwRemainSize -= sizeof(*pPackHdr);
if ( pPackHdr->len > dwRemainSize )
{
SwapRecvProcessBuffers();
break;
}
//将缓冲读取指针调整到下一个通信数据包的位置
pDataBuffer->pPointer += sizeof(*pPackHdr) + pPackHdr->len;
if ( pPackHdr->len >= sizeof(nCmd) )
{
//将通信数据段保存在packet中
CDataPacketReader packet(pPackHdr + 1, pPackHdr->len);
//分派数据包处理
packet >> nCmd;
OnDispatchRecvPacket(nCmd, packet);
}
else
{
OutputMsg(rmError, _T("%s recv invalid server packet, packet size to few(%d)"),
getClientName(), pPackHdr->len);
}
}
}
VOID CCustomJXServerClientSocket::Disconnected()
{
Inherited::Disconnected();
m_boRegisted = false;
m_sClientName[0] = 0;
m_nClientSrvIdx = 0;
m_eClientType = InvalidServer;
}

View File

@@ -0,0 +1,213 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
#include <Windows.h>
#include <tchar.h>
//#include <WinSock2.h>
#endif
#include <_ast.h>
#include <_memchk.h>
#include <CustomSocket.h>
#include <Tick.h>
#include <Lock.h>
#include <QueueList.h>
#include "ShareUtil.h"
#include "BufferAllocator.h"
#include "AppItnMsg.h"
#include "DataPacket.hpp"
#include "SendPackPool.h"
#include "CustomWorkSocket.h"
#include "CustomServerClientSocket.h"
#include "CustomServerClientSocketEx.h"
CCustomServerClientSocketEx::CCustomServerClientSocketEx()
:Inherited(),
InheritedThread("CCustomServerClientSocketEx")
{
m_bStop = false;
//m_hSendDataThread = INVALID_HANDLE_VALUE;
//m_hStopEvent = INVALID_HANDLE_VALUE;
SetSendDataInSingleRun(false);
}
CCustomServerClientSocketEx::CCustomServerClientSocketEx(SOCKET nSocket, SOCKADDR_IN *pClientAddr)
{
SetClientSocket(nSocket, pClientAddr);
}
CCustomServerClientSocketEx::~CCustomServerClientSocketEx()
{
//if (m_hSendDataThread != INVALID_HANDLE_VALUE)
{
m_bStop = true;
OutputMsg(rmNormal, _T("ServerClientSocketEx发送线程退出"));
//WaitForSingleObject(m_hStopEvent, INFINITE);
//OutputMsg(rmNormal, _T("ServerClientSocketEx发送线程退出"));
//CloseHandle(m_hSendDataThread);
}
}
void CCustomServerClientSocketEx::StartWork()
{
/*
if (m_hSendDataThread != INVALID_HANDLE_VALUE)
return;
m_bStop = false;
if (INVALID_HANDLE_VALUE == m_hStopEvent)
m_hStopEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
m_hSendDataThread = ::CreateThread(NULL, 0, staticSendDataRountine, this, 0, NULL);
*/
OutputMsg(rmNormal, _T("ServerClientSocketEx发送线启动"));
StartWorkThread();
//InheritedThread::resume();
}
void CCustomServerClientSocketEx::StopWork()
{
/*
if (m_hSendDataThread != INVALID_HANDLE_VALUE)
{
m_bStop = true;
OutputMsg(rmNormal, _T("等待ServerClientSocketEx发送线程退出"));
WaitForSingleObject(m_hStopEvent, INFINITE);
OutputMsg(rmNormal, _T("ServerClientSocketEx发送线程退出"));
CloseHandle(m_hSendDataThread);
}
*/
OutputMsg(rmNormal, _T("ServerClientSocketEx发送线程退出"));
StopWorkThread();
}
/*
DWORD CCustomServerClientSocketEx::staticSendDataRountine(LPVOID pParam)
{
CCustomServerClientSocketEx* pThis = (CCustomServerClientSocketEx *)pParam;
pThis->SendDataRoutine();
return 0;
}
*/
//void OnRountine();
void CCustomServerClientSocketEx::OnRountine()
{
INT_PTR nMaxLoopSendCount = 2;
static INT_PTR nLoopCount = 0;
fd_set fdwrite;
struct timeval tv = {1, 0};
//while (!m_bStop)
{
if (!connected())
{
Sleep(50);
return;
}
if (sendToSocketEx(*this) > 0)
{
m_dwMsgTick = _getTickCount();
}
if (m_SendingPacketList.count() > 0)
{
FD_ZERO(&fdwrite);
SOCKET fd = getSocket() ;
if( fd < 0 ) return ;
FD_SET(fd, &fdwrite);
#ifdef WIN32
int nRet = select(0, NULL, &fdwrite, NULL, &tv);
#else
int nRet = select(fd+1, NULL, &fdwrite, NULL, &tv);
#endif
if (nRet < 0)
{
OutputMsg(rmError, _T("select except: %d"), nRet);
Sleep(10);
}
// 不管是出错还是等待超时,还是缓冲区可以写数据,都返回
return;
}
else
{
nLoopCount++;
if (nLoopCount >= nMaxLoopSendCount)
{
nLoopCount = 0;
Sleep(30);
}
}
}
//SetEvent(m_hStopEvent);
}
size_t CCustomServerClientSocketEx::sendToSocketEx(CCustomSocket& socket)
{
INT_PTR nCount, nAvalLength, nBytesWriten;
CDataPacket **pPacketList, *pPacket;
size_t nTotalSent = 0;
//提交追加到发送队列中的数据包
if (m_SendingPacketList.count() <= 0)
m_SendingPacketList.flush();
//循环发送数据包
nCount = m_SendingPacketList.count();
if (nCount <= 0)
return 0;
pPacketList = m_SendingPacketList;
for (; m_nSendingPacketIdx<nCount; ++m_nSendingPacketIdx)
{
pPacket = pPacketList[m_nSendingPacketIdx];
nAvalLength = pPacket->getAvaliableLength();
if (nAvalLength > 0)
{
//发送数据
nBytesWriten = socket.send(pPacket->getOffsetPtr(), (INT)nAvalLength);
if ( nBytesWriten <= 0 )
{
break;
}
}
else nBytesWriten = 0;
nTotalSent += nBytesWriten;
//该数据包中的数据是否已经发完
if (nBytesWriten >= nAvalLength)
{
//清空数据包的数据长度
pPacket->setLength(0);
}
else
{
//调整偏移到下次继续发送的位置
pPacket->adjustOffset(nBytesWriten);
break;
}
}
//如果发送队列中的数据已经全部发送完毕,则将数据包全部移动到空闲数据包列表中
// 计算已经发送完毕的数据包的数量
if ( m_nSendingPacketIdx >= nCount || m_nSendingPacketIdx >= 20)
{
INT_PTR nSendCount = m_nSendingPacketIdx;
//OutputMsg(rmTip, _T(" sendPackIdx=%d nCount=%d"), nSendCount, nCount);
m_nSendingPacketIdx = 0;
m_FreeSendPackList.lock();
m_FreeSendPackList.addArray(m_SendingPacketList, nSendCount);
m_FreeSendPackList.unlock();
m_SendingPacketList.remove(0, nSendCount);
}
return nTotalSent;
}
//VOID CCustomServerClientSocketEx::SendSocketBuffers()
//{
// //Inherited::SendSocketBuffers();
//}

View File

@@ -0,0 +1,684 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
#include <tchar.h>
#include <Windows.h>
#endif
#include <_ast.h>
#include <_memchk.h>
#include <QueueList.h>
#include <Tick.h>
#include <Lock.h>
#include <Thread.h>
#include <CustomSocket.h>
#include "ServerDef.h"
#include "GateProto.h"
#include "ShareUtil.h"
#include "BufferAllocator.h"
#include "AppItnMsg.h"
#include "DataPacket.hpp"
#include "DataPacketReader.hpp"
#include "SendPackPool.h"
#include "CustomWorkSocket.h"
#include "CustomServerClientSocket.h"
#include "CustomServerClientSocketEx.h"
#include "CustomServerSocket.h"
#include "CustomServerGateUser.h"
#include "CustomServerGate.h"
#include "CustomGateManager.h"
CCustomServerGate::CCustomServerGate()
{
m_sGateName[0] = 0;
m_nGateIndex = 0;
m_bHasPrintErrInfo = false;
ZeroMemory(&m_GateUserInfo, sizeof(m_GateUserInfo));
#ifndef _USE_GATE_SEND_PACK_LIST_
ZeroMemory( &m_SendBufQueue, sizeof(m_SendBufQueue) );
m_pSendAppendBuffer = &m_SendBufQueue[0];
m_pSendProcBuffer = &m_SendBufQueue[1];
InitializeCriticalSection( &m_WriteLock );
#endif
}
CCustomServerGate::~CCustomServerGate()
{
CloseAllUser();
FreeBuffers();
#ifndef _USE_GATE_SEND_PACK_LIST_
DeleteCriticalSection( &m_WriteLock );
#endif
}
VOID CCustomServerGate::FreeBuffers()
{
#ifndef _USE_GATE_SEND_PACK_LIST_
//释放发送数据缓冲区内存
SafeFree( m_SendBufQueue[0].pBuffer );
m_SendBufQueue[0].nSize = 0;
m_SendBufQueue[0].nOffset = 0;
SafeFree( m_SendBufQueue[1].pBuffer );
m_SendBufQueue[1].nSize = 0;
m_SendBufQueue[1].nOffset = 0;
#else
clearSendList();
#endif
}
VOID CCustomServerGate::SocketError(INT nErrorCode)
{
OutputError(nErrorCode, _T("[GATE]%s(%s:%d)socket error"), m_sGateName, GetRemoteHost(), GetRemotePort());
Inherited::SocketError(nErrorCode);
}
VOID CCustomServerGate::Disconnected()
{
Inherited::Disconnected();
OutputMsg(rmWaning, _T("[GATE]%s(%s:%d) closed"), m_sGateName, GetRemoteHost(), GetRemotePort());
FreeBuffers();
CloseAllUser();
m_sGateName[0] = 0;
}
VOID CCustomServerGate::SendKeepAlive()
{
#ifndef _USE_GATE_SEND_PACK_LIST_
GATEMSGHDR MsgHdr;
MsgHdr.dwGateCode = RUNGATECODE;
MsgHdr.nSocket = 0;
MsgHdr.wIdent = GM_CHECKCLIENT;
MsgHdr.nDataSize = 0;
AddGateBuffer( &MsgHdr, sizeof(MsgHdr) );
#else
CDataPacket &packet = AllocGateSendPacket(0, 0);
PGATEMSGHDR pMsgHdr = (PGATEMSGHDR)packet.getMemoryPtr();
pMsgHdr->wIdent = GM_CHECKCLIENT;
pMsgHdr->tickCount = _getTickCount();
FlushGateSendPacket(packet);
#endif
}
VOID CCustomServerGate::ProcessRecvBuffers(PDATABUFFER pDataBuffer)
{
INT_PTR nLen, nCheckMsgLen;
char *pBuf, *pMsgBuf;
PGATEMSGHDR pMsgHdr;
BOOL boTipNotRunGateCode;
//如果连接已断开则丢弃所有数据
if ( !connected() )
{
OutputMsg( rmWaning, _T("ProcessRecvBuffers,socket is close ,drop data") );
Inherited::ProcessRecvBuffers(pDataBuffer);
SwapRecvProcessBuffers();
return;
}
nLen = 0;
pBuf = NULL;
//nLen = pDataBuffer->nOffset;
pBuf = pDataBuffer->pPointer;
nLen = pDataBuffer->nOffset - (pBuf - pDataBuffer->pBuffer);
if (!m_bHasPrintErrInfo && pBuf != pDataBuffer->pBuffer)
{
m_bHasPrintErrInfo = true;
OutputMsg(rmError, _T("CCustomServerGate::ProcessRecvBuffers pPointer != pBuffer"));
}
//处理数据包的条件是接收缓冲的长度不少于一个网关通信消息头
if ( nLen >= sizeof(*pMsgHdr) )
{
boTipNotRunGateCode = FALSE;
while ( TRUE )
{
pMsgHdr = (PGATEMSGHDR)pBuf;
nCheckMsgLen = pMsgHdr->nDataSize + sizeof(*pMsgHdr);
//检查协议头是否有效dwGateCode必须是RUNGATECODE
if ( pMsgHdr->dwGateCode == RUNGATECODE && nCheckMsgLen < 0x8000 )//丢弃长度大于0x8000的数据包
{
boTipNotRunGateCode = FALSE;
if ( nLen < nCheckMsgLen )
break;
pMsgBuf = pBuf + sizeof(*pMsgHdr);
DispathRecvMessage( pMsgHdr, pMsgBuf, pMsgHdr->nDataSize );
pBuf += sizeof(*pMsgHdr) + pMsgHdr->nDataSize;
nLen -= sizeof(*pMsgHdr) + pMsgHdr->nDataSize;
}
else
{
pBuf++;
nLen--;
if ( !boTipNotRunGateCode )
{
boTipNotRunGateCode = TRUE;
OutputMsg( rmWaning, _T("%s droped a packed(not RUNGATECODE)"), _T(__FUNCTION__) );
}
}
if ( nLen < sizeof(*pMsgHdr) )
break;
}
pDataBuffer->pPointer = pBuf;
}
SwapRecvProcessBuffers();
}
VOID CCustomServerGate::DispatchInternalMessage(UINT uMsg, UINT64 uParam1, UINT64 uParam2, UINT64 uParam3,UINT64 uParam4)
{
switch (uMsg)
{
//按用户SOCKET关闭用户
case SGIM_CLOSE_USER_SOCKET:
OutputMsg(rmTip,"CCustomServerGate::DispatchInternalMessage, close socket=%d",(int)uParam1);
CloseUser(uParam1);
break;
//按用户SOCKET以及用户在服务器中的会话编号关闭用户
case SGIM_CLOSE_USER_SOCKET_SIDX:
OutputMsg(rmTip,"CCustomServerGate::DispatchInternalMessage, CloseUser socket=%d",(int)uParam1);
CloseUser(uParam1, (int)uParam2);
break;
//按用户的全局会话ID关闭用户Param1=全局会话ID
case SGIM_CLOSE_USER_SOCKET_GSID:
OutputMsg(rmTip,"CCustomServerGate::DispatchInternalMessage, CloseUser account=%d",(int)uParam1);
CloseUserByGlobalSessionId((int)uParam1);
break;
case SGIM_KICK_USER_SOCKET_GSID:
OutputMsg(rmTip,"CCustomServerGate::DispatchInternalMessage, kick user account=%d",(int)uParam1);
KickUserByGlobalSessionId((int)uParam1);
break;
}
}
VOID CCustomServerGate::DispathRecvMessage(PGATEMSGHDR pMsgHdr, char *pBuffer, SIZE_T nBufSize)
{
int nUserIndex;
if (pMsgHdr->wIdent != GM_CHECKSERVER)
{
//OutputMsg( rmTip, _T("收到网关的数据!, cmd=%d,nBufSize=%d"), pMsgHdr->wIdent,nBufSize );
}
switch ( pMsgHdr->wIdent )
{
//打开新用户
case GM_OPEN:
{
nUserIndex = (int)OpenNewUser( pMsgHdr->nSocket, pMsgHdr->wSessionIdx, pBuffer );
SendAcceptUser( pMsgHdr->nSocket, pMsgHdr->wSessionIdx, nUserIndex + 1 );
}
break;
//关闭用户
case GM_CLOSE:
OutputMsg(rmTip,"CCustomServerGate::DispathRecvMessage GM_CLOSE,SOCKET=%d ",(int)pMsgHdr->nSocket);
CloseUser( pMsgHdr->nSocket,false ); //网关通知关闭的就不回消息过去了
break;
//网关发送的心跳包
case GM_CHECKSERVER:
{
nUserIndex = m_sGateName[0];
_asncpytA( m_sGateName, pBuffer );
if ( !nUserIndex )
{
OutputMsg(rmTip, _T("[GATE]%s:%d registed(%s)"), GetRemoteHost(), GetRemotePort(), m_sGateName);
}
SendKeepAlive();
}
break;
case GM_GATEUSERINFO:
if (nBufSize == sizeof(GATEUSERINFO))
{
CopyMemory(&m_GateUserInfo, pBuffer, nBufSize);
}
break;
//网关转发用户数据
case GM_DATA:
case GM_APPKEEPALIVEACK:
PostUserData( pMsgHdr, pBuffer, nBufSize );
break;
}
}
VOID CCustomServerGate::SingleRun()
{
Inherited::SingleRun();
if ( connected() )
{
#ifndef _USE_GATE_SEND_PACK_LIST_
SendGateBuffers();
#endif
}
}
INT_PTR CCustomServerGate::OpenNewUser(UINT64 nSocket, int nGateSessionIndex, char *sIPAddr)
{
INT_PTR i, nIndex;
CCustomServerGateUser *pUser, **pUserList;
pUser = CreateGateUser();
//从用户列表中找到一个空闲的用户位置指针为NULL的位置
//如果有空闲的位置则将用户放置在空闲处
nIndex = -1;
pUserList = m_UserList;
for ( i=m_UserList.count()-1; i>-1; --i )
{
if ( !pUserList[i] )
{
pUserList[i] = pUser;
nIndex = i;
break;
}
}
//未能将用户放置再空闲处则添加到用户列表的末尾
if ( nIndex < 0 )
{
nIndex = m_UserList.add( pUser );
}
//初始化网关用户对象
pUser->nSocket = nSocket;
pUser->nGateSessionIndex = nGateSessionIndex;
pUser->nServerSessionIndex = (int)nIndex;
_asncpytA(pUser->sIPAddr, sIPAddr);
pUser->dwConnectTick = pUser->dwLastMsgTick = _getTickCount();
pUser->dwDelayCloseTick = 0;
pUser->boMarkToClose = FALSE;
//TRACE(_T("创建连接Socket=%d,nGateSessionIndex=%d,nServerIndex=%d\n"),nSocket,nGateSessionIndex,nIndex +1);
//回调打开用户的函数
OnOpenUser(pUser);
return nIndex;
}
CCustomServerGateUser* CCustomServerGate::CreateGateUser()
{
return new CCustomServerGateUser();
}
VOID CCustomServerGate::DestroyGateUser(CCustomServerGateUser* pUser)
{
SafeDelete(pUser);
}
VOID CCustomServerGate::OnOpenUser(CCustomServerGateUser* pUser)
{
}
VOID CCustomServerGate::OnCloseUser(CCustomServerGateUser* pUser)
{
}
VOID CCustomServerGate::OnGateClosed()
{
}
VOID CCustomServerGate::SendAcceptUser(UINT64 nSocket, int nGateSessionIndex, int nServerSessionIndex)
{
#ifndef _USE_GATE_SEND_PACK_LIST_
GATEMSGHDR MsgHdr;
MsgHdr.dwGateCode = RUNGATECODE;
MsgHdr.nSocket = nSocket;
MsgHdr.wSessionIdx = (WORD)nGateSessionIndex;
MsgHdr.wIdent = GM_SERVERUSERINDEX;
MsgHdr.wServerIdx = (WORD)nServerSessionIndex;
MsgHdr.nDataSize = 0;
AddGateBuffer( &MsgHdr, sizeof(MsgHdr) );
#else
CDataPacket &packet = AllocGateSendPacket(nSocket, nGateSessionIndex,nServerSessionIndex);
PGATEMSGHDR pMsgHdr = (PGATEMSGHDR)packet.getMemoryPtr();
pMsgHdr->wIdent = GM_SERVERUSERINDEX;
//pMsgHdr->wServerIdx = (WORD)nServerSessionIndex;
FlushGateSendPacket(packet);
OutputMsg(rmTip,_T("[Login] (4) 告诉网关已添加玩家gate socket(%lld)GateIdx(%d)LogicIdx(%d)CurrentThreadId(%d)。"),
nSocket,nGateSessionIndex,nServerSessionIndex,GetCurrentThreadId());
#endif
}
VOID CCustomServerGate::PostCloseGateServer()
{
#ifndef _USE_GATE_SEND_PACK_LIST_
GATEMSGHDR MsgHdr;
MsgHdr.dwGateCode = RUNGATECODE;
MsgHdr.nSocket = 0;
MsgHdr.wIdent = GM_CLOSE_SERVER;
MsgHdr.nDataSize = 0
AddGateBuffer( &MsgHdr, sizeof(MsgHdr) );
#else
CDataPacket &packet = AllocGateSendPacket(0, 0);
PGATEMSGHDR pMsgHdr = (PGATEMSGHDR)packet.getMemoryPtr();
pMsgHdr->wIdent = GM_CLOSE_SERVER;
pMsgHdr->tickCount =0;
FlushGateSendPacket(packet);
#endif
}
VOID CCustomServerGate::CloseUser(const UINT64 nSocket,bool bNeedTellGate)
{
INT_PTR i;
CCustomServerGateUser **pUserList;
OutputMsg(rmNormal, _T("CCustomServerGate::CloseUser: socket=%d"), (int)nSocket);
pUserList = m_UserList;
for ( i=m_UserList.count()-1; i>-1; --i )
{
if ( pUserList[i] && pUserList[i]->nSocket == nSocket )
{
GateUserClosed( pUserList[i] ,bNeedTellGate);
pUserList[i] = NULL;
//TRACE( "被动关闭网关用户连接\n" );
break;
}
}
}
VOID CCustomServerGate::CloseUser(const UINT64 nSocket, const int nServerSessionIndex,bool bNeedTellGate)
{
OutputMsg(rmNormal, _T("CCustomServerGate::CloseUser2: socket=%d,srvIndex=%d"), (int)nSocket,int(nServerSessionIndex));
if ( nServerSessionIndex >= 0 && nServerSessionIndex < m_UserList.count() )
{
if ( m_UserList[nServerSessionIndex] && m_UserList[nServerSessionIndex]->nSocket == nSocket )
{
GateUserClosed( m_UserList[nServerSessionIndex],bNeedTellGate );
m_UserList[nServerSessionIndex] = NULL;
}
else
{
//OutputMsg(rmWaning,_T("用户索引中指定位置的用户不存在或套接字句柄未能匹配\n"));
}
}
}
VOID CCustomServerGate::CloseUserByGlobalSessionId(const int nGlobalSessionId)
{
INT_PTR nIndex;
CCustomServerGateUser *pUserList = UserExistsOfGlobalSessionId(nGlobalSessionId, &nIndex);
if ( pUserList )
{
GateUserClosed( pUserList );
m_UserList[nIndex] = NULL;
}
}
VOID CCustomServerGate::KickUserByGlobalSessionId(const int nGlobalSessionId)
{
INT_PTR nIndex;
CCustomServerGateUser *pUserList = UserExistsOfGlobalSessionId(nGlobalSessionId, &nIndex);
if ( pUserList )
{
GateUserClosed( pUserList );
m_UserList[nIndex] = NULL;
}
}
CCustomServerGateUser* CCustomServerGate::UserExistsOfGlobalSessionId(const int nGlobalSessionId, PINT_PTR pIndex)
{
INT_PTR i;
CCustomServerGateUser **pUserList;
pUserList = m_UserList;
for ( i=m_UserList.count()-1; i>-1; --i )
{
if ( pUserList[i] && pUserList[i]->nGlobalSessionId == nGlobalSessionId )
{
if ( pIndex ) *pIndex = i;
return pUserList[i];
}
}
return NULL;
}
VOID CCustomServerGate::CloseAllUser()
{
INT_PTR i;
CCustomServerGateUser **pUserList;
CCustomServerGateUser *pGateUser;
pUserList = m_UserList;
for ( i=m_UserList.count() -1; i>-1; --i )
{
if ( pUserList[i] )
{
pGateUser = pUserList[i];
pUserList[i] = NULL;
GateUserClosed(pGateUser);
}
}
m_UserList.clear();
}
VOID CCustomServerGate::GateUserClosed(CCustomServerGateUser *pGateUser,bool bNeedTellGate)
{
OutputMsg(rmNormal, _T("CCustomServerGate::GateUserClosed socket=%d, sessionId=%d, serverId=%d"), (int)pGateUser->nSocket,
(int)pGateUser->nGateSessionIndex, (int)pGateUser->nServerSessionIndex);
if(bNeedTellGate)
{
SendGateCloseUser(pGateUser->nSocket, pGateUser->nGateSessionIndex,pGateUser->nServerSessionIndex);
}
OnCloseUser(pGateUser);
pGateUser->nSocket = 0;
pGateUser->nGlobalSessionId = 0;
pGateUser->nServerSessionIndex = 0;
pGateUser->nGateSessionIndex = 0;
//添加到空闲用户列表中
DestroyGateUser( pGateUser );
}
VOID CCustomServerGate::SendGateCloseUser(UINT64 nSocket, int nGateSessionIndex,int nServerIndex)
{
#ifndef _USE_GATE_SEND_PACK_LIST_
GATEMSGHDR MsgHdr;
MsgHdr.dwGateCode = RUNGATECODE;
MsgHdr.nSocket = nSocket;
MsgHdr.wSessionIdx = (WORD)nGateSessionIndex;
MsgHdr.wIdent = GM_CLOSE;
MsgHdr.wServerIdx = (WORD)nServerIndex;
MsgHdr.nDataSize = 0;
AddGateBuffer( &MsgHdr, sizeof(MsgHdr) );
#else
OutputMsg(rmNormal, _T("关闭Socket=%d, nGateSessionIndex=%d\n"),nSocket, nGateSessionIndex);
CDataPacket &packet = AllocGateSendPacket(nSocket, nGateSessionIndex,nServerIndex);
PGATEMSGHDR pMsgHdr = (PGATEMSGHDR)packet.getMemoryPtr();
pMsgHdr->wIdent = GM_CLOSE;
//pMsgHdr->wServerIdx =(WORD)nServerIndex;
FlushGateSendPacket(packet);
#endif
}
VOID CCustomServerGate::PostUserData(PGATEMSGHDR pMsgHdr, char *pData, SIZE_T nDataSize)
{
INT_PTR i;
CCustomServerGateUser *pGateUser, **pGateUserList;
//按用户的服务器索引查找用户
pGateUser = NULL;
if ( pMsgHdr->wServerIdx > 0 && pMsgHdr->wServerIdx <= m_UserList.count() )
{
pGateUser = m_UserList.get(pMsgHdr->wServerIdx - 1);
if ( pGateUser && pGateUser->nSocket != pMsgHdr->nSocket )
{
pGateUser = NULL;
}
}
//如果没有找到用户则从用户表中遍历查找用户
if ( !pGateUser )
{
pGateUserList = m_UserList;
for ( i=m_UserList.count()-1; i>-1; --i )
{
if ( pGateUserList[i] && pGateUserList[i]->nSocket == pMsgHdr->nSocket )
{
pGateUser = pGateUserList[i];
//找到用户后重新向网关发送设定用户服务端索引的消息
SendAcceptUser( pMsgHdr->nSocket, pMsgHdr->wSessionIdx, (int)i + 1 );
TRACE(_T("%s reget user server-index\n"),__FUNCTION__);
break;
}
}
}
if ( pGateUser && !pGateUser->boMarkToClose && pGateUser->dwDelayCloseTick == 0 )
{
/*
//减少一个字节从网关发送过来的数据增加了一个字节表示为0终止符此处不需要终止符。
if ( nDataSize > 0 ) nDataSize--;
*/
//调用处理用户数据的函数
pGateUser->dwGateTickCount = pMsgHdr->tickCount;//带网关的tickcount过来
OnDispatchUserMsg(pGateUser, pData, nDataSize);
}
}
#ifndef _USE_GATE_SEND_PACK_LIST_
VOID CCustomServerGate::AddGateBuffer(LPCVOID pBuffer, SIZE_T nBufferSize)
{
PDATABUFFER pDataBuf;
if ( !pBuffer || nBufferSize <= 0 || !connected() ) return ;
EnterCriticalSection( &m_WriteLock );
pDataBuf = m_pSendAppendBuffer;
if ( pDataBuf->nSize < (INT_PTR)(pDataBuf->nOffset + nBufferSize) )
{
pDataBuf->nSize += (pDataBuf->nSize / 8192 + 1) * 8192;
pDataBuf->pBuffer = (char*)realloc( pDataBuf->pBuffer, pDataBuf->nSize );
}
memcpy( &pDataBuf->pBuffer[pDataBuf->nOffset], pBuffer, nBufferSize );
pDataBuf->nOffset += nBufferSize;
LeaveCriticalSection( &m_WriteLock );
}
VOID CCustomServerGate::AddUserBuffer(SOCKET nUserSocket, INT_PTR nGateSessionIndex, LPCVOID pBuffer, SIZE_T nBufferSize)
{
static const size_t MemAlginmentSize = 8192;//发送缓冲内存块边界大小必须是2的次方数
PGATEMSGHDR pMsgHdr;
INT_PTR nNeedSize;
char *pBuf;
PDATABUFFER pDataBuf;
if ( !pBuffer || nBufferSize <= 0 || !connected() ) return;
EnterCriticalSection( &m_WriteLock );
pDataBuf = m_pSendAppendBuffer;
nNeedSize = pDataBuf->nOffset + sizeof(*pMsgHdr) + nBufferSize;
if ( pDataBuf->nSize < nNeedSize )
{
pDataBuf->nSize *= 2;
if ( pDataBuf->nSize < nNeedSize )
{
pDataBuf->nSize = (nNeedSize / MemAlginmentSize + 1) * MemAlginmentSize;
}
pDataBuf->pBuffer = (char*)realloc( pDataBuf->pBuffer, pDataBuf->nSize );
}
pBuf = pDataBuf->pBuffer + pDataBuf->nOffset;
pMsgHdr = (PGATEMSGHDR)pBuf;
pBuf += sizeof(*pMsgHdr);
pMsgHdr->dwGateCode = RUNGATECODE;
pMsgHdr->nSocket = nUserSocket;
pMsgHdr->wSessionIdx= (WORD)nGateSessionIndex;
pMsgHdr->wIdent = GM_DATA;
pMsgHdr->nDataSize = (INT)nBufferSize;
memcpy( pBuf, pBuffer, nBufferSize );
pDataBuf->nOffset += sizeof(*pMsgHdr) + nBufferSize;
LeaveCriticalSection( &m_WriteLock );
}
VOID CCustomServerGate::SendGateBuffers()
{
static const INT_PTR OnceSendBytes = 8192;//每次通信最大发送数据长度
PDATABUFFER pDataBuf;
int nBytesWriten, nSendSize;
if ( m_pSendProcBuffer->nOffset <= 0 )
{
EnterCriticalSection( &m_WriteLock );
pDataBuf = m_pSendProcBuffer;
m_pSendProcBuffer = m_pSendAppendBuffer;
m_pSendAppendBuffer = pDataBuf;
m_pSendProcBuffer->pPointer = m_pSendProcBuffer->pBuffer;
LeaveCriticalSection( &m_WriteLock );
}
pDataBuf = m_pSendProcBuffer;
while ( pDataBuf->nOffset > 0 )
{
nSendSize = (INT)pDataBuf->nOffset;
if ( nSendSize > OnceSendBytes )
nSendSize = OnceSendBytes;
nBytesWriten = send( pDataBuf->pPointer, nSendSize );
//连接断开了
if ( nBytesWriten <= 0 )
break;
//调整发包缓冲指针以及剩余包长度
pDataBuf->pPointer += nBytesWriten;
pDataBuf->nOffset -= nBytesWriten;
if ( pDataBuf->nOffset <= 0 )
pDataBuf->nOffset = 0;
//如果发送的字节长度少于需求发送的长度则表明发送缓冲已经满了
if ( nBytesWriten < nSendSize )
break;
}
}
#else
CDataPacket& CCustomServerGate::AllocGateSendPacket(UINT64 nUserSocket, int nGateSessionIndex,int nServerIndex)
{
CDataPacket *pPacket;
allocSendPacketList(*((CBaseList<CDataPacket*>*)NULL), 0, &pPacket);
PGATEMSGHDR pMsgHdr;
pPacket->setLength(sizeof(*pMsgHdr));
pPacket->setPosition(sizeof(*pMsgHdr));
pMsgHdr = (PGATEMSGHDR)pPacket->getMemoryPtr();
pMsgHdr->dwGateCode = RUNGATECODE;
pMsgHdr->nSocket = nUserSocket;
pMsgHdr->wSessionIdx= (WORD)nGateSessionIndex;
pMsgHdr->wIdent = GM_DATA;
pMsgHdr->wServerIdx =(WORD )nServerIndex;
return *pPacket;
}
VOID CCustomServerGate::FlushGateSendPacket(CDataPacket& packet)
{
//向网关通信头中写入用户数据包长度
PGATEMSGHDR pMsgHdr = (PGATEMSGHDR)packet.getMemoryPtr();
pMsgHdr->nDataSize = (int)packet.getLength() - sizeof(*pMsgHdr);
flushSendPacket(packet);
}
VOID CCustomServerGate::FlushGateBigPacket(CDataPacket& packet)
{
flushSendPacket(packet);
}
#endif

View File

@@ -0,0 +1,352 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
#include <tchar.h>
#include <Windows.h>
#endif
#include <_ast.h>
#include <_memchk.h>
#include <Thread.h>
#include <CustomSocket.h>
#include <Tick.h>
#include <Lock.h>
#include <QueueList.h>
#include "ShareUtil.h"
#include "BufferAllocator.h"
#include "AppItnMsg.h"
#include "DataPacket.hpp"
#include "CommonDef.h"
#include "ServerDef.h"
#include "SendPackPool.h"
#include "CustomWorkSocket.h"
#include "CustomServerClientSocket.h"
#include "CustomClientSocket.h"
#include "CustomJXClientSocket.h"
#include "CustomJXServerClientSocket.h"
#include "InterServerComm.h"
//#include "../encrypt/CRC.h"
//#include "../encrypt/Encrypt.h"
//#include "../dataProcess/NetworkDataHandler.h"
#include "CustomJXClientSocket.h"
#include "CustomGlobalSession.h"
#include "CustomSessionClient.h"
using namespace jxSrvDef;
using namespace jxInterSrvComm;
const CCustomSessionClient::OnHandleSockPacket CCustomSessionClient::SSSockPacketHandlers[] =
{
&CCustomSessionClient::CatchDefaultPacket,
&CCustomSessionClient::CatchOpenSession,
&CCustomSessionClient::CatchCloseSession,
&CCustomSessionClient::CatchUpdateSession,
&CCustomSessionClient::CatchQuerySessionExists,
};
CCustomSessionClient::CCustomSessionClient()
:Inherited()
{
SetClientName(_T("会话"));
}
CCustomSessionClient::~CCustomSessionClient()
{
}
VOID CCustomSessionClient::OnDispatchRecvPacket(const jxSrvDef::INTERSRVCMD nCmd, CDataPacketReader &inPacket)
{
if ( nCmd >= ArrayCount(SSSockPacketHandlers) )
{
OutputMsg(rmWaning, _T("SessionServer[%s:%d]has sent invalid packet(%d)datalen%d"),
GetServerHost(), GetServerPort(), nCmd, inPacket.getLength());
}
else
{
(this->*SSSockPacketHandlers[nCmd])(inPacket);
}
}
VOID CCustomSessionClient::CatchDefaultPacket(CDataPacketReader &inPacket)
{
}
VOID CCustomSessionClient::CatchOpenSession(CDataPacketReader &inPacket)
{
BOOL boNewSession = FALSE;
GLOBALSESSIONOPENDATA SessionData;
inPacket >> SessionData;
OutputMsg(rmTip,"%s sessionid=%d",__FUNCTION__,SessionData.nSessionId);
if ( SessionData.nSessionId && SessionData.sAccount[0] )
{
CCustomGlobalSession* pSession = GetSessionPtr(SessionData.nSessionId, NULL,SessionData.lKey);
if ( !pSession )
{
pSession = CreateSession();
//填充会话基本数据
pSession->nSessionId = SessionData.nSessionId;
pSession->nServerIndex = SessionData.nServerIndex;
pSession->nRawServerId = SessionData.nRawServerId;
pSession->nClientIPAddr = SessionData.nClientIPAddr;
pSession->dwSessionTick = _getTickCount();
pSession->nState = SessionData.eState;
pSession->dwFCMOnlineSec = SessionData.dwFCMOnlineSec;
pSession->nGmLevel = SessionData.nGmLevel; //账户的GM等级
_asncpytA(pSession->sAccount, SessionData.sAccount);
pSession->lKey = SessionData.lKey;
pSession->nGateIndex = SessionData.nGateIndex;
//将会话添加到全局会话队列中
m_SessionLock.Lock();
m_SessionList.add(pSession);
m_SessionLock.Unlock();
boNewSession = TRUE;
//test
//OutputMsg(rmTip,"CustomSeesionClient Open Session,nSessionId=%d,nServerIndex=%d",
// pSession->nSessionId,pSession->nServerIndex);
}
else
{
//设置成新的值
pSession->nSessionId = SessionData.nSessionId;
pSession->nServerIndex = SessionData.nServerIndex;
pSession->nRawServerId = SessionData.nRawServerId;
pSession->nClientIPAddr = SessionData.nClientIPAddr;
pSession->dwSessionTick = _getTickCount();
pSession->nState = SessionData.eState;
pSession->dwFCMOnlineSec = SessionData.dwFCMOnlineSec;
pSession->nGmLevel = SessionData.nGmLevel;
_asncpytA(pSession->sAccount, SessionData.sAccount);
pSession->lKey = SessionData.lKey;
pSession->nGateIndex = SessionData.nGateIndex;
}
OnOpenSession(pSession, boNewSession);
}
}
VOID CCustomSessionClient::CatchCloseSession(CDataPacketReader &inPacket)
{
int nSessionId;
UINT64 lKey =0; //玩家的key
inPacket >> nSessionId >>lKey ;//<<----从通信数据包中获取全局会话ID
OutputMsg(rmTip,"%s sessionid=%d",__FUNCTION__,nSessionId);
INT_PTR nIdx;
CCustomGlobalSession *pSession = GetSessionPtr(nSessionId, &nIdx,lKey);
if ( pSession )
{
//调用会话删除的通知函数
OnCloseSession(pSession);
//test
//OutputMsg(rmTip,"CustomSeesionClient Close Session,nSessionId=%d,nServerIndex=%d",
// pSession->nSessionId,pSession->nServerIndex);
m_SessionList.remove(nIdx);
DestroySession(pSession);
}
else
{
OutputMsg(rmTip,"CatchCloseSession id=%d, pSession is NULL",nSessionId);
}
}
VOID CCustomSessionClient::CatchUpdateSession(CDataPacketReader &inPacket)
{
int nSessionId = 0;
GSSTATE nNewState = gsSelChar;
UINT64 lKey =0;
inPacket >> nSessionId;//<<----从通信数据包中获取全局会话ID
inPacket >> nNewState;//<----从通信数据包中获取会话的状态值
inPacket >> lKey;//<----
CCustomGlobalSession *pSession = GetSessionPtr( nSessionId, NULL,lKey );
if ( pSession )
{
GSSTATE nOldState = pSession->nState;
pSession->nState = nNewState;
//调用关于会话状态变更的通知函数
OnUpdateSessionState(pSession, nOldState, nNewState);
}
}
VOID CCustomSessionClient::CatchQuerySessionExists(CDataPacketReader &inPacket)
{
int nSessionId = 0;
inPacket >> nSessionId;//<<----从通信数据包中获取全局会话ID
//调用查询会话是否在线的函数
OnQuerySessionExists(nSessionId);
}
/*
void CCustomSessionClient::SendKeepAlive()
{
#pragma __CPMSG__(发送保持连接的心跳包)
//flushProtoPacket(allocProtoPacket());
}
*/
CCustomGlobalSession* CCustomSessionClient::GetSessionPtr(const INT_PTR nSessionID, PINT_PTR pIndex,UINT64 lKey)
{
INT_PTR i;
CCustomGlobalSession **pSessionList;
pSessionList = m_SessionList;
for (i=m_SessionList.count()-1; i>-1; --i)
{
if ( pSessionList[i]->nSessionId == nSessionID && pSessionList[i]->lKey == lKey)
{
if (pIndex) *pIndex = i;
return pSessionList[i];
}
}
return NULL;
}
VOID CCustomSessionClient::ClearSessionList()
{
INT_PTR i;
CCustomGlobalSession **pSessionList;
CSafeLock sl(&m_SessionLock);
pSessionList = m_SessionList;
for (i=m_SessionList.count()-1; i>-1; --i)
{
if ( pSessionList[i] )
{
DestroySession(pSessionList[i]);
}
}
m_SessionList.clear();
}
VOID CCustomSessionClient::DispatchInternalMessage(UINT uMsg, UINT64 uParam1, UINT64 uParam2, UINT64 uParam3,UINT64 uParam4)
{
CCustomGlobalSession *pSession;
WORD cmd = 0;
switch(uMsg)
{
case SSIM_RESULT_SESSION_EXISTS:
cmd = jxInterSrvComm::SessionServerProto::cQueryResult;
break;
case SSIM_CHG_SESSION_STATE:
cmd = jxInterSrvComm::SessionServerProto::cUpdateSession ;
break;
case SSIM_CLOSE_SESSION:
cmd = jxInterSrvComm::SessionServerProto::cCloseSession ;
break;
default:
return;
}
CDataPacket &data = allocProtoPacket(cmd); //分配一个 网络包
switch (uMsg)
{
case SSIM_RESULT_SESSION_EXISTS://返回查询会话是否在线的结果 uParam1=全局会话IDuParam2=在线?1:0
{
//返回会话服务器用户是否存在
data << (int) uParam1;
data << (BYTE) uParam2;
break;
}
case SSIM_CHG_SESSION_STATE://改变会话状态 uParam1=全局会话IDuParam2=会话状态值为GSSTATE的枚举值
{
pSession = GetSessionPtr(uParam1, NULL,uParam3);
if ( pSession )
{
pSession->nState = (GSSTATE)uParam2;
//向会话服务器发送改变会话状态的消息
data << (int) uParam1;
data << (int) uParam2;
}
else
{
OutputMsg(rmWaning,_T("SSIM_CHG_SESSION_STATE 改变会话的时候没有找到需要改变状态的会话%d\n"), (int)uParam1);
}
}
break;
case SSIM_CLOSE_SESSION://关闭会话 uParam1=全局会话ID
{
pSession = GetSessionPtr(uParam1, NULL,uParam2);
if ( pSession )
{
//如果会话的状态不是等待连接下一个服务器的状态则关闭会话
//if ( pSession->nState != gsWaitQueryChar && pSession->nState != gsWaitEntryGame )
data << (int) uParam1 << UINT64(uParam2);
}
else
{
data << (int) 0 << 0;
OutputMsg(rmWaning,_T("SSIM_CLOSE_SESSION 没有找到需要关闭的会话%d\n"), (int)uParam1);
}
}
break;
}
flushProtoPacket(data);
}
CCustomGlobalSession* CCustomSessionClient::CreateSession()
{
return (CCustomGlobalSession*)m_Allocator.AllocBuffer(sizeof(CCustomGlobalSession));
}
VOID CCustomSessionClient::DestroySession(CCustomGlobalSession* pSession)
{
m_Allocator.FreeBuffer(pSession);
}
VOID CCustomSessionClient::OnWorkThreadStop()
{
ClearSessionList();
}
bool CCustomSessionClient::GetSessionData(const int nSessionID,UINT64 lKey,OUT PGLOBALSESSIONOPENDATA pSessionData)
{
INT_PTR i;
bool boResult = false;
CCustomGlobalSession **pSessionList, *pSession;
CSafeLock sl(&m_SessionLock);
pSessionList = m_SessionList;
for (i=m_SessionList.count()-1; i>-1; --i)
{
if ( pSessionList[i]->nSessionId == nSessionID && lKey== pSessionList[i]->lKey)
{
pSession = pSessionList[i];
//填充会话基本数据
pSessionData->nSessionId = (INT)pSession->nSessionId;
pSessionData->nServerIndex = (INT)pSession->nServerIndex;
pSessionData->nRawServerId = pSession->nRawServerId;
pSessionData->nClientIPAddr = pSession->nClientIPAddr;
pSessionData->dwFCMOnlineSec = pSession->dwFCMOnlineSec;
pSessionData->eState = pSession->nState;
pSessionData->nGmLevel = pSession->nGmLevel; //GM等级
_asncpytA(pSessionData->sAccount, pSession->sAccount);
boResult = true;
}
}
return boResult;
}
VOID CCustomSessionClient::OnConnected()
{
Inherited::OnConnected();
}

View File

@@ -0,0 +1,103 @@
//#include "Stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
#include <crtdbg.h>
#include <tchar.h>
#include <Windows.h>
#endif
#include <_ast.h>
#include <_memchk.h>
//#include <Thread.h>
#include <CustomSocket.h>
#include <Lock.h>
#include <Tick.h>
#include <Stream.h>
//#include <QueueList.h>
#include <LinkedList.h>
#include "ShareUtil.h"
#include <RefString.hpp>
//#include <math.h>
#include "HandleStat.h"
void HandleMgrCollector::addHangleMgrStat(const HandleMgrStat *stat)
{
if (!stat) return;
m_handleMgrCollector.linkAfter(stat);
}
void HandleMgrCollector::removeHandleMgrStat(const HandleMgrStat *stat)
{
if (!stat) return;
using namespace wylib::container;
CLinkedListIterator<const HandleMgrStat*> iter(m_handleMgrCollector);
CLinkedNode<const HandleMgrStat*> *pNode = 0;
for (pNode = iter.first(); pNode; pNode = iter.next())
{
if (pNode->m_Data == stat)
{
iter.remove(pNode);
return;
}
}
}
void HandleMgrCollector::logToFile()
{
/* 文件格式:
---------------------------------------------------------------------------
DateTime:2010-10-20 19:30
HandleMgrName UsedHandleCount AllocedBlockNum HandlePerBlock
***
---------------------------------------------------------------------------
*/
using namespace wylib::stream;
using namespace wylib::container;
char name[128];
time_t szClock;
time(&szClock);
struct tm curTime;
localtime_r(&szClock, &curTime);
sprintf(name,"HandleMgrProf_%d_%d_%d.log",(int)curTime.tm_year,(int)curTime.tm_mon,(int)curTime.tm_mday);
CFileStream fs(name, CFileStream::faWrite, CFileStream::AlwaysOpen);
fs.setPosition(fs.getSize());
const TCHAR szSep[] = _T("-------------------------------------------------------------------------------------------\r\n");
TCHAR szDateTime[250] = {0};
_tcsftime(szDateTime, _tcslen(szDateTime)-1, _T("%Y-%m-%d %H:%M:%S\r\n"), &curTime);
fs.write(szSep, _tcslen(szSep));
fs.write(szDateTime, _tcslen(szDateTime));
TCHAR szDesc[256] = {0};
_stprintf(szDesc, _T("%-40s%-25s%-25s%-25s%-25s\r\n"), _T("HandleMgrName"), _T("UsedHandleCount"), _T("MaxUsedHdlCount"), _T("AllocedBlockNum"), _T("HandlePerBlock"));
fs.write(szDesc, _tcslen(szDesc));
TCHAR szContent[256] = {0};
TCHAR szContentFmt[256] = {0};
_tcscpy(szContentFmt, _T("%-40s%-25I64u%-25I64u%-25I64u%-25I64u\r\n"));
CLinkedListIterator<const HandleMgrStat*> iter(m_handleMgrCollector);
CLinkedNode<const HandleMgrStat*> *pNode = 0;
for (pNode = iter.first(); pNode; pNode = iter.next())
{
const HandleMgrStat *stat = pNode->m_Data;
if (stat)
{
unsigned long long nCntPerChunk, nChunkCount, nUsedCnt, nMaxUsedCnt;
stat->getStatInfo(nCntPerChunk, nChunkCount, nUsedCnt, nMaxUsedCnt);
_stprintf(szContent, szContentFmt, stat->getObjectDesc(), nUsedCnt, nMaxUsedCnt, nChunkCount, nCntPerChunk);
fs.write(szContent, _tcslen(szContent));
}
}
fs.write(szSep, _tcslen(szSep));
}

View File

@@ -0,0 +1,298 @@
#include <stdio.h>
#include<stdlib.h>
#ifdef WIN32
#include <tchar.h>
#include <Windows.h>
#endif
#include <_ast.h>
#include <_memchk.h>
#include <zlib.h>
#include "Stream.h"
#include "ZStream.h"
#include "JXAbsGameMap.h"
#include <BufferAllocator.h>
using namespace jxcomm::gameMap;
using namespace wylib::stream;
using namespace wylib::zstream;
//地图文件头标志
const DWORD MapFileHeaderIdent = 0x00504D57;
//地图版本号定义
const DWORD MapFileVersion_101116 = 0x000A0B10;
const DWORD MapFileVersion_101206 = 0x000A0C06;
//使用战将2的资源
const DWORD MapFileVersion_120320 = 0x000A0302;
//当前地图版本号
const DWORD MapFileVersion_Current = MapFileVersion_120320;
//不可移动标记
const UINT_PTR MAPFLAG_MOVEABLE = 0x8000;
#define USE_NEW_MAPFILE_HEADER
/*
* 地图文件头结构
*/
typedef struct tagJXMapFileHeader
{
/*
DWORD dwIdent; //文件头标识固定为0x004D584A
DWORD dwVersion; //文件版本固定为0x000A0B0F
INT nWidth; //地图宽度
INT nHeight; //地图高度
INT nBackground; //地图背景图片编号
DWORD dwDataSize; //地图坐标数据段字节长度
BYTE btReseve[40];
*/
#ifdef USE_NEW_MAPFILE_HEADER
//char hdr_[5]; // "map"
//int dwVersion; // 文件版本固定为0x000A0B0F
//unsigned char dwDataSize; // 常量64像素
//int pxi_width_; // 地图的像素大小
//int pix_height_;
int nWidth; // 地图宽度
int nHeight; // 地图高度
#else
unsigned int dwVersion; // 文件版本0x0101
int nWidth; // 地图宽度
int nHeight; // 地图高度
int bg_img_; // 地图背景图片编号
unsigned int dwDataSize; // 地图坐标数据段字节长度
unsigned char reseve_[32];
#endif
}MAPFILE_HEADER, *PMAPFILE_HEADER;
enum GripFlag
{
gfBlock = 0, //阻挡
gfCanMove = 1, //行走区
gfThrough = 2, //透明区
gfNofly = 3, //阻挡且不能飞跃
};
/*
* 地图坐标完整结构
*/
typedef struct tagJXMapCell
{
unsigned char wFlag; // 0=阻档1=行走区,2=透明区,3=阻挡且不能飞跃
}MAPCELL, *PMAPCELL;
CAbstractMap::CAbstractMap()
{
m_dwWidth = 0;
m_dwHeight = 0;
m_pGridData = NULL;
m_pMoveableIndex = NULL;
m_nMoveableCount = 0;
m_nBBoxT = 0;
m_nBBoxL = 0;
m_nBBoxR = 0;
m_nBBoxB = 0;
m_pAllocator = new CBufferAllocator();
//m_pWayPointMap =NULL;
//m_nWayPointCount =0;
}
CAbstractMap::~CAbstractMap()
{
if ( m_pMoveableIndex )
m_pAllocator->FreeBuffer(m_pMoveableIndex);
if (m_pGridData)
m_pAllocator->FreeBuffer(m_pGridData);
if (m_pAllocator)
free(m_pAllocator);
/*
if(m_pWayPointMap)
{
free(m_pWayPointMap);
}
*/
}
/*
int CAbstractMap::GetMapPosValue(int x,int y)
{
return getMoveableIndex(x,y);
}
*/
bool CAbstractMap::LoadFromStream(CBaseStream& stream)
{
MAPFILE_HEADER hdr;
MAPCELL* map_grid, *grid_ptr;
//将压缩过的坐标数据段读取到内存流
CMemoryStream ms;
ms.copyFrom(stream, stream.getSize());
ms.setPosition(0);
//从内存流中创建解压流,以便解压坐标数据
//CZDecompressionStream deStream(ms);
CMemoryStream& deStream = ms;
int max = 0;
//读取并检查文件头
if (deStream.read(&hdr, sizeof(hdr)) != sizeof(hdr))
return false;
// 地图打包文件,按照大头的字节序打包了
//hdr.nWidth = ntohl(hdr.nWidth);
//hdr.nHeight = ntohl(hdr.nHeight);
size_t grid_count = sizeof(MAPCELL) * hdr.nWidth * hdr.nHeight;
if (m_pGridData) m_pAllocator->FreeBuffer(m_pGridData);
m_pGridData = grid_ptr = map_grid = (MAPCELL*)m_pAllocator->AllocBuffer(grid_count);
if (grid_count != (const size_t)deStream.read(map_grid, (const int)grid_count))
return false;
max = hdr.nWidth * hdr.nHeight;
m_nMoveableCount = 0;
if (m_pMoveableIndex) m_pAllocator->FreeBuffer(m_pMoveableIndex);
BYTE* index_ptr = m_pMoveableIndex = (BYTE*)m_pAllocator->AllocBuffer(max * sizeof(*index_ptr));
memset(index_ptr, 0, max * sizeof(*index_ptr)); // 如果是memset其他值会有问题
// 这个索引值跟旧版本的不一样
for (int i = 0; i < max; ++i)
{
if (grid_ptr->wFlag != gfBlock /*&& grid_ptr->wFlag != gfNofly*/)//不是明确的不可走点,都认为可走就行了
{
int x = i / hdr.nHeight;
int y = i % hdr.nHeight;
*(index_ptr + (y * hdr.nWidth + x)) = grid_ptr->wFlag;
m_nMoveableCount++;
}
grid_ptr++;
}
//保存地图宽度以及高度数据
m_dwWidth = hdr.nWidth;
m_dwHeight = hdr.nHeight;
return true;
}
/*
bool CAbstractMap::LoadFromStream(CBaseStream& stream)
{
MAPFILE_HEADER hdr;
size_t dwCellSize;
PMAPCELL pMapCell, pMapCellPtr;
//读取并检查文件头
if ( stream.read(&hdr, sizeof(hdr)) != sizeof(hdr) )
{
return false;
}
if ( hdr.dwIdent != MapFileHeaderIdent )
{
return false;
}
if ( hdr.dwVersion != MapFileVersion_Current )
{
return false;
}
INT_PTR nTotalSize= stream.getSize(); //获取文件的大小
INT_PTR nDataSize = nTotalSize - sizeof(hdr); //减去头的长度就是数据的长度
//将压缩过的坐标数据段读取到内存流
CMemoryStream ms;
ms.copyFrom(stream, nDataSize);
ms.setPosition(0);
//从内存流中创建解压流,以便解压坐标数据
CZDecompressionStream deStream(ms);
dwCellSize = sizeof(*pMapCell) * hdr.nWidth * hdr.nHeight;
pMapCellPtr = pMapCell = (PMAPCELL)malloc(dwCellSize);
if ( dwCellSize != deStream.read(pMapCell, dwCellSize) )
return false;
//生成抽象灰度地图
int i, max = hdr.nWidth * hdr.nHeight;
m_nMoveableCount = 0;
int nIntCount = max/32 +1; //占用多少个Int
BYTE* pMoveIndex = m_pMoveableIndex = (BYTE*) realloc(m_pMoveableIndex, max * sizeof(*pMoveIndex));
memset(pMoveIndex, 0, max * sizeof(*pMoveIndex));
m_nBBoxL = hdr.nWidth;
m_nBBoxT = hdr.nHeight;
for ( i=0; i<max; ++i)
{
if ((pMapCellPtr->wFlag & MAPFLAG_MOVEABLE) == 0)
{
*pMoveIndex = 1;
m_nMoveableCount++;
int nY = i / hdr.nWidth; //y坐标
int nX = i % hdr.nWidth; //x坐标
if (m_nBBoxL > nX)
m_nBBoxL = nX;
else if (nX > m_nBBoxR)
m_nBBoxR = nX;
if (m_nBBoxT > nY)
m_nBBoxT = nY;
else if (nY > m_nBBoxB)
m_nBBoxB = nY;
}
pMoveIndex++;
pMapCellPtr++;
}
//保存地图宽度以及高度数据
m_dwWidth = hdr.nWidth;
m_dwHeight = hdr.nHeight;
free(pMapCell);
return true;
}
*/
bool CAbstractMap::LoadFromFile(LPCTSTR sFileName)
{
CFileStream fs(sFileName, CFileStream::faRead || CFileStream::faShareRead);
return LoadFromStream(fs);
}
void CAbstractMap::initDefault(DWORD dwWidth, DWORD dwHeight)
{
//生成抽象灰度地图
int i, max = dwWidth * dwHeight;
m_nMoveableCount = 0;
if (m_pMoveableIndex) m_pAllocator->FreeBuffer(m_pMoveableIndex);
BYTE* pMoveIndex = m_pMoveableIndex = (BYTE*)m_pAllocator->AllocBuffer(max * sizeof(*pMoveIndex));
for ( i=0; i<max; ++i)
{
(*pMoveIndex) = 1;
m_nMoveableCount++;
pMoveIndex++;
}
//保存地图宽度以及高度数据
m_dwWidth = dwWidth;
m_dwHeight = dwHeight;
}

View File

@@ -0,0 +1,598 @@
#include <stdlib.h>
#include <stdio.h>
#ifdef WIN32
#include <tchar.h>
#include <WinSock2.h>
#include <Windows.h>
#endif
#include <_ast.h>
#include <_memchk.h>
#include <Tick.h>
#include <Lock.h>
#include <QueueList.h>
#include <CustomSocket.h>
#include "ShareUtil.h"
#include "BufferAllocator.h"
#include "AppItnMsg.h"
#include "DataPacket.hpp"
#include "SendPackPool.h"
#include "CustomWorkSocket.h"
#include "CustomClientSocket.h"
#include "ServerDef.h"
#include "LogType.h"
//#include "encrypt\CRC.h"
//#include "encrypt\Encrypt.h"
//#include "dataProcess\NetworkDataHandler.h"
#include "CustomJXClientSocket.h"
#include "LogSender.h"
using namespace jxSrvDef;
LogSender::LogSender(jxSrvDef::SERVERTYPE ServerType,INT ServerIndex,char* ServerName)
{
this->ServerType = ServerType;
this->ServerIndex = ServerIndex;
strcpy(this->ServerName,ServerName);
this->SetClientName(_T("日志"));
}
LogSender::LogSender()
{
this->SetClientName(_T("日志"));
}
LogSender::~LogSender(void)
{
}
//设置服务器的编号
VOID LogSender::SetServerIndex(const INT nSerIdx)
{
ServerIndex = nSerIdx;
}
VOID LogSender::SetServerName(LPCTSTR sServerName)
{
_tcsncpy(ServerName, sServerName, ArrayCount(ServerName) - 1);
ServerName[ArrayCount(ServerName) - 1] = 0;
}
void LogSender::SetServerSpid(LPCTSTR sSpid)
{
_tcsncpy(m_sSpid, sSpid, ArrayCount(m_sSpid) - 1);
m_sSpid[ArrayCount(m_sSpid) - 1] = 0;
}
VOID LogSender::SendLoginLog(WORD nLogid,int nUserid,LPCTSTR szAccount,
LPCTSTR szLoginIp,LPCTSTR szLoginDescr, int nLevel, int nYb, unsigned int nOnlineTime, unsigned int nActorId,unsigned int nSrvId)
{
LOGDATALOGIN data;
data.nCmdId = LOG_LOGIN_CMD;
data.nLogid = nLogid;
data.nUserid = nUserid;
data.nLevel = nLevel;
data.nYb = nYb;
data.nOnlineTime = nOnlineTime;
if (szAccount != NULL)
{
_asncpytA((data.szAccount),szAccount);
}
else
{
data.szAccount[0] = 0;
}
data.nServerIndex = ServerIndex;
data.nSrvId = ServerIndex;
if(nSrvId > 0)
{
data.nServerIndex = nSrvId;
}
if (szLoginIp != NULL)
{
_asncpytA((data.szLoginIp),szLoginIp);
}
else
{
data.szLoginIp[0] = 0;
}
data.nServerType = ServerType;
if (szLoginDescr != NULL)
{
_asncpytA((data.szLoginDescr),szLoginDescr);
}
else
{
data.szLoginDescr[0] = 0;
}
//_asncpytA(data.szSpid, m_sSpid);
snprintf(data.szSpid, sizeof(data.szSpid), "%d", nActorId);
////组装成网络包
CDataPacket &pdata = allocProtoPacket(data.nCmdId); //分配一个 网络包
pdata << data;
flushProtoPacket(pdata);
//OutputMsg( rmTip, _T("发送登陆日志CmdId=%d,Logid=%d,Userid=%dAccount=%s,ServerIndex=%d,LoginIp=%s,ServerType=%d,LoginDescr=%s"),
// data.nCmdId,data.nLogid,data.nUserid,data.szAccount,data.nServerIndex,data.szLoginIp,data.nServerType,data.szLoginDescr);
}
VOID LogSender::SendConsumeLog(WORD nLogid,int nActorid,LPCTSTR szAccount,
LPCTSTR szCharName,BYTE nMoneytype,int nCount,int nPaymentCount,LPCTSTR szConsumeDescr,int nLevel, int nBalance, unsigned int nSrvId)
{
LOGDATACONSUME data;
data.nCmdId = LOG_CONSUME_CMD;
data.nLogid = nLogid;
data.nActorid = nActorid;
data.nConsumeLevel =nLevel; //玩家的消费的等级
if (szAccount != NULL)
{
_asncpytA((data.szAccount),szAccount);
}
else
{
data.szAccount[0] = 0;
}
data.nServerIndex = ServerIndex;
data.nSrvId = ServerIndex;
if(nSrvId > 0)
{
data.nServerIndex = nSrvId;
}
if (szCharName != NULL)
{
_asncpytA((data.szCharName),szCharName);
}
else
{
data.szCharName[0] = 0;
}
data.cMoneytype = nMoneytype;
data.nBalance = nBalance;
data.nConsumecount = nCount;
data.nPaymentCount = nPaymentCount;
if (szConsumeDescr != NULL)
{
_asncpytA((data.szConsumeDescr),szConsumeDescr);
}
else
{
data.szConsumeDescr[0] = 0;
}
//_asncpytA(data.szSpid, m_sSpid);
snprintf(data.szSpid, sizeof(data.szSpid), "%d", nActorid);
////组装成网络包
CDataPacket &pdata = allocProtoPacket(data.nCmdId); //分配一个 网络包
pdata << data;
flushProtoPacket(pdata);
//OutputMsg( rmTip, _T("发送消费日志CmdId=%d,Logid=%d,Userid=%dAccount=%s,ServerIndex=%d,CharName=%s,ConsumeCount=%d,PaymentCount=%d,ConsumeDescr=%s"),
// data.nCmdId,data.nLogid,data.nUserid,data.szAccount,data.nServerIndex,data.szCharName,data.nConsumeCount,data.nPaymentCount,data.szConsumeDescr);
}
VOID LogSender::SendItemLocalLog(
BYTE nType,
WORD nLogid,
int nActorid,
int nAccountid,
LPCTSTR szAccount,
LPCTSTR szCharName,
WORD wItemId,
int nCount,
LPCTSTR szConsumeDescr,
unsigned int nSrvId)
{
LOGDATAITEM data;
data.nCmdId = LOG_ITEAM_CMD;
data.nLogid = nLogid;
data.nActorid = nActorid;
data.nType = nType;
if (szAccount != NULL)
{
_asncpytA((data.szAccount),szAccount);
}
else
{
data.szAccount[0] = 0;
}
data.nServerIndex = ServerIndex;
data.nSrvId = ServerIndex;
if(nSrvId > 0)
{
data.nServerIndex = nSrvId;
}
if (szCharName != NULL)
{
_asncpytA((data.szCharName),szCharName);
}
else
{
data.szCharName[0] = 0;
}
data.wItemId = wItemId;
data.nCount = nCount;
if (szConsumeDescr != NULL)
{
_asncpytA((data.szConsumeDescr),szConsumeDescr);
}
else
{
data.szConsumeDescr[0] = 0;
}
//_asncpytA(data.szSpid, m_sSpid);
snprintf(data.szSpid, sizeof(data.szSpid), "%d", nAccountid);
////组装成网络包
CDataPacket &pdata = allocProtoPacket(data.nCmdId); //分配一个 网络包
pdata << data;
flushProtoPacket(pdata);
//OutputMsg( rmTip, _T("发送消费日志CmdId=%d,Logid=%d,Userid=%dAccount=%s,ServerIndex=%d,CharName=%s,ConsumeCount=%d,PaymentCount=%d,ConsumeDescr=%s"),
// data.nCmdId,data.nLogid,data.nUserid,data.szAccount,data.nServerIndex,data.szCharName,data.nConsumeCount,data.nPaymentCount,data.szConsumeDescr);
}
VOID LogSender::SendDealToLog(int nLogid, unsigned int nTime,
int nActorid,int nTarActorid,
INT nItemId,WORD nItemNum,WORD nMoneyType,INT64 nMoneyNum, int nDues, unsigned int nSrvId)
{
LOGACTORDEALSAVE tmpLog;
tmpLog.nLogId = nLogid;
tmpLog.nMiniTime = nTime;
tmpLog.nActorid = nActorid;
tmpLog.nTarActorid = nTarActorid;
tmpLog.nItemId = nItemId;
tmpLog.nItemNum = nItemNum;
tmpLog.nMoneyType = nMoneyType;
tmpLog.nMoneyNum = nMoneyNum;
tmpLog.nDues = nDues;
tmpLog.nServerIndex = ServerIndex;
tmpLog.nSrvId = ServerIndex;
if(nSrvId > 0)
{
tmpLog.nServerIndex = nSrvId;
}
_asncpytA(tmpLog.szSpid, m_sSpid);
CDataPacket &pdata = allocProtoPacket(LOG_DEAL_CMD);
pdata << tmpLog;
flushProtoPacket(pdata);
}
VOID LogSender::SendOnlineLog(int nServerIndex,int nCount)
{
LOGDATAONLINECOUNT data;
data.nCmdId = LOG_ONLINE_CMD;
data.nServerIndex = nServerIndex;
data.nOnlineCount = nCount;
_asncpytA(data.szSpid, m_sSpid);
////组装成网络包
CDataPacket &pdata = allocProtoPacket(data.nCmdId); //分配一个 网络包
pdata << data;
flushProtoPacket(pdata);
//OutputMsg( rmTip, _T("发送在线日志CmdId=%d,ServerIndex=%d,OnlineCount=%d"),
// data.nCmdId,data.nServerIndex,data.nOnlineCount);
}
VOID LogSender::SendSuggestLog( int nType,char * sActorName,char * sAccount, char * sTitle, char * sDetail,int nLevel, unsigned int nSrvId)
{
LOGGERDATASUGGEST data;
data.nCmdId = LOG_SUGGEST_CMD;
if (sActorName != NULL)
{
_asncpytA((data.szCharName),sActorName);
}
else
{
data.szCharName[0] = 0;
}
if (sAccount != NULL)
{
_asncpytA((data.szAccount),sAccount);
}
else
{
data.szAccount[0] = 0;
}
if (sTitle != NULL)
{
_asncpytA((data.szTitle),sTitle);
}
else
{
data.szTitle[0] = 0;
}
if (sDetail != NULL)
{
_asncpytA((data.szSuggest),sDetail);
}
else
{
data.szSuggest[0] = 0;
}
data.nType = (WORD)nType;
data.nServerIndex= (WORD)ServerIndex;
data.nActorLevel = nLevel;
////组装成网络包
CDataPacket &pdata = allocProtoPacket(data.nCmdId); //分配一个 网络包
pdata << data;
flushProtoPacket(pdata);
}
VOID LogSender::SendCommonLog(WORD nLogid,int nUserid,LPCTSTR szAccount,
int nPara0,int nPara1,int nPara2,
LPCTSTR szShortStr0,LPCTSTR szMidStr0,LPCTSTR szLongStr0,
LPCTSTR szShortStr1,LPCTSTR szMidStr1,LPCTSTR szLongStr1,
LPCTSTR szMidStr2,LPCTSTR szLongStr2, unsigned int nSrvId)
{
LOGGERDATACOMMON data;
data.nCmdId = LOG_COMMON_CMD;
data.nLogid = nLogid;
data.nActorid = nUserid;
if (szAccount != NULL)
{
_asncpytA((data.szAccount),szAccount);
}
else
{
data.szAccount[0] = 0;
}
data.nServerIndex = ServerIndex;
data.nSrvId = ServerIndex;
if(nSrvId > 0)
{
data.nServerIndex = nSrvId;
}
data.nPara0 = nPara0;
data.nPara1 = nPara1;
data.nPara2 = nPara2;
if (szShortStr0 != NULL)
{
_asncpytA((data.szShortStr0),szShortStr0);
}
else
{
data.szShortStr0[0] = 0;
}
if (szShortStr1 != NULL)
{
_asncpytA((data.szShortStr1),szShortStr1);
}
else
{
data.szShortStr1[0] = 0;
}
if (szMidStr0 != NULL)
{
_asncpytA((data.szMidStr0),szMidStr0);
}
else
{
data.szMidStr0[0] = 0;
}
if (szMidStr1 != NULL)
{
_asncpytA((data.szMidStr1),szMidStr1);
}
else
{
data.szMidStr1[0] = 0;
}
if (szMidStr2 != NULL)
{
_asncpytA((data.szMidStr2),szMidStr2);
}
else
{
data.szMidStr2[0] = 0;
}
if (szLongStr0 != NULL)
{
_asncpytA((data.szLongStr0),szLongStr0);
}
else
{
data.szLongStr0[0] = 0;
}
if (szLongStr1 != NULL)
{
_asncpytA((data.szLongStr1),szLongStr1);
}
else
{
data.szLongStr1[0] = 0;
}
if (szLongStr2 != NULL)
{
_asncpytA((data.szLongStr2),szLongStr2);
}
else
{
data.szLongStr2[0] = 0;
}
_asncpytA(data.szSpid, m_sSpid);
////组装成网络包
CDataPacket &pdata = allocProtoPacket(data.nCmdId); //分配一个 网络包
pdata << data;
flushProtoPacket(pdata);
//OutputMsg( rmTip, _T("发送公共日志CmdId=%d,Logid=%d,Userid=%dAccount=%s,ServerIndex=%d,para0=%d,para1=%d,para2=%d,ShortStr0=%s,ShortStr1=%s,MidStr0=%s,MidStr1=%s,MidStr2=%s,LongStr0=%s,LongStr1=%s,LongStr2=%s"),
// data.nCmdId,data.nLogid,data.nUserid,data.szAccount,data.nServerIndex,data.nPara0,data.nPara1,data.nPara2
// ,data.szShortStr0,data.szShortStr1,data.szMidStr0,data.szMidStr1,data.szMidStr2,data.szLongStr0,data.szLongStr1,data.szLongStr2);
}
VOID LogSender::SendChatLog(int nChannleID, char * sActorName,unsigned int nActorId, char * msg)
{
if(!sActorName || !msg) return;
if(m_nFlag)
{
CDataPacket &pdata = allocProtoPacket(LOG_SENDCHATRECORD_CMD); //分配一个 网络包
pdata << (int)nChannleID;
pdata << (unsigned int)nActorId;
pdata.writeString(sActorName);
pdata.writeString(msg);
flushProtoPacket(pdata);
}
}
VOID LogSender::OnDispatchRecvPacket(const jxSrvDef::INTERSRVCMD nCmd, CDataPacketReader &inPacket)
{
//空函数,本身不处理日志服务器下发的消息
switch(nCmd)
{
case LOG_LOOKCHATMSG_CMD:
{
int nFlag = 0;
inPacket >> nFlag;
SetChatLogFlag(nFlag);
break;
}
}
}
jxSrvDef::SERVERTYPE LogSender::getLocalServerType()
{
return ServerType;
}
LPCSTR LogSender::getLocalServerName()
{
return ServerName;
}
int LogSender::getLocalServerIndex()
{
return ServerIndex;
}
VOID LogSender::OnConnected()
{
CDataPacket &pdata = allocProtoPacket(LOG_SENDSERVERINDEX_CMD); //分配一个 网络包
pdata << (int)ServerIndex;
flushProtoPacket(pdata);
}
VOID LogSender::SendKillDropLog(int nActorid,LPCTSTR sAccount,LPCTSTR sCharName,
LPCTSTR sMonName,LPCTSTR sSceneName,LPCTSTR sItemName,int nCount, int nKilltime, int nPosX, int nPosY, unsigned int nSrvId)
{
LOGKILLDROP data;
data.nCmdId = LOG_KILLDROP_CMD;
data.nServerIndex = ServerIndex;
data.nSrvId = ServerIndex;
if(nSrvId > 0)
{
data.nServerIndex = nSrvId;
}
data.nActorid = nActorid;
data.nKilltime = nKilltime;
if (sAccount != NULL)
{
_asncpytA((data.srtAccount),sAccount);
}
else
{
data.srtAccount[0] = 0;
}
if (sCharName != NULL)
{
_asncpytA((data.strName),sCharName);
}
else
{
data.strName[0] = 0;
}
if (sMonName != NULL)
{
_asncpytA((data.strMonsetName),sMonName);
}
else
{
data.strMonsetName[0] = 0;
}
if (sSceneName != NULL)
{
_asncpytA((data.strSceneName),sSceneName);
}
else
{
data.strSceneName[0] = 0;
}
if (sItemName != NULL)
{
_asncpytA((data.strItemName),sItemName);
}
else
{
data.strItemName[0] = 0;
}
data.nCount = nCount;
data.nPosx = nPosX;
data.nPosy = nPosY;
////组装成网络包
CDataPacket &pdata = allocProtoPacket(data.nCmdId); //分配一个 网络包
pdata << data;
flushProtoPacket(pdata);
//OutputMsg( rmTip, _T("发送公共日志CmdId=%d,Logid=%d,Userid=%dAccount=%s,ServerIndex=%d,para0=%d,para1=%d,para2=%d,ShortStr0=%s,ShortStr1=%s,MidStr0=%s,MidStr1=%s,MidStr2=%s,LongStr0=%s,LongStr1=%s,LongStr2=%s"),
// data.nCmdId,data.nLogid,data.nUserid,data.szAccount,data.nServerIndex,data.nPara0,data.nPara1,data.nPara2
// ,data.szShortStr0,data.szShortStr1,data.szMidStr0,data.szMidStr1,data.szMidStr2,data.szLongStr0,data.szLongStr1,data.szLongStr2);
}
VOID LogSender::SendJoinAtvToLog(int nActorid,LPCTSTR sAccount,LPCTSTR sCharName,int nAtvId, int nIndex, int nJoinTime, unsigned int nSrvId)
{
LOGATVSCHEDULE data;
data.nCmdId = LOG_JOINATV_CMD;
data.nServerIndex = ServerIndex;
data.nSrvId = ServerIndex;
if(nSrvId > 0)
{
data.nServerIndex = nSrvId;
}
data.nActorid = nActorid;
data.nAtvID = nAtvId;
if (sAccount != NULL)
{
_asncpytA((data.srtAccount),sAccount);
}
else
{
data.srtAccount[0] = 0;
}
if (sCharName != NULL)
{
_asncpytA((data.strName),sCharName);
}
else
{
data.strName[0] = 0;
}
data.nIndex = nIndex;
data.nJoinTime = nJoinTime;
////组装成网络包
CDataPacket &pdata = allocProtoPacket(data.nCmdId); //分配一个 网络包
pdata << data;
flushProtoPacket(pdata);
}

View File

@@ -0,0 +1,212 @@
/************************************************************
* 实现网络数据包到逻辑数据包变换
* 为了标示网络数据的长度和开始信息网络包将添加头部标示tag和长度以及checkSum等头部信息
* 该类讲从网络包里组装出逻辑数据,用于处理,如果是默认的话
***********************************************************/
#ifdef WIN32
#include <Windows.h>
#endif
#include "crc.h"
#include "Encrypt.h"
#include "NetworkDataHandler.h"
CNetworkDataHandler::CNetworkDataHandler(bool bNeedEncrypt)
{
m_bNeedEncrypt = bNeedEncrypt;
m_nTag = DEFAULT_TAG_VALUE;
}
bool CNetworkDataHandler::DataUnpack(char *pInBuff,SIZE_T nInSize, char *pOutBuff, SIZE_T nOutSize,SIZE_T & nInProcessSize,SIZE_T & nOutProcessSize,bool bWithHeader,Encrypt * pEncrypt)
{
/*
nOutProcessSize =0;
nInProcessSize =0;
SIZE_T nHeaderSize = sizeof(DATAHEADER);
if (nInSize < nHeaderSize ) return false; //输入的数据不够
if (NULL == pInBuff || NULL == pOutBuff) return false;
if (m_bNeedEncrypt && pEncrypt ==NULL ) return false; //如果需要加密的话,又没有传入加密的指针
bool tagFlag =false; //tag的寻找标志
SIZE_T i =0;
WORD * pTagPos =NULL;
for ( ;i < nInSize -1; i++)
{
pTagPos = (WORD *)(pInBuff + i);
if(*pTagPos == m_nTag) //如果找到了tag
{
tagFlag = true; //找到了头
break;
}
}
//如果没有找到,那么
if (tagFlag ==false )
{
i ++;
}
nInProcessSize = i; //前面的几个字节,如果不是头,将说明是垃圾数据,将被干掉
SIZE_T nLeftCount = nInSize - i; //还有多少个字节再后面
//剩下的数据不够头,或者没有找到头
if (tagFlag ==false || nLeftCount < nHeaderSize )
{
if (nInProcessSize >0)
{
return true;
}
else
{
return false;
}
}
DATAHEADER data; //把数据拷贝一份过来
memcpy( (void *)&data,(void*) (pInBuff + i),nHeaderSize ); //拷贝一份
PDATAHEADER pHeader = &data; //把后面的转换为数据头的指针
SIZE_T nTotalPackSize = pHeader->len + nHeaderSize ; //一个完整的数据包的需要的长度
if ( nTotalPackSize > nLeftCount ) return false; //数据不齐全没有len个字节发送过来
bool bEncryptFlag = ! m_bNeedEncrypt ; //取反
if(m_bNeedEncrypt)
{
pEncrypt->Decode((char *)(pInBuff + i + sizeof(data.tag) + sizeof(data.len)),sizeof(data.EncodePart) ,(char *)&(data.EncodePart)); //进行解密操作
WORD hdrSum = data.EncodePart.hdrSum; //把这个checkSum保持起来
if(pEncrypt)
{
data.EncodePart.hdrSum = pEncrypt->GetCheckSum();
}
else
{
data.EncodePart.hdrSum = DEFAULT_HEADER_CHECK_SUM ; //用默认值替换完以后再计算整个头部的checkSum
}
if ( (0xffff &pEncrypt->CRC16((unsigned char *)&data,nHeaderSize )) == hdrSum ) //头部校验成功
{
if ( (0xffff &pEncrypt->CRC16( (unsigned char *)(pInBuff + i +nHeaderSize ),pHeader->len ) ) == data.EncodePart.dataSum)
{
bEncryptFlag =true; //验证成功
}
}
}
if (bEncryptFlag )
{
if ( bWithHeader ) //需要把数据头带出去
{
if( nTotalPackSize <= nOutSize )
{
//拷贝数据
memcpy(pOutBuff,(void *)(pInBuff + i +nHeaderSize ),nTotalPackSize) ;
nInProcessSize = i + nTotalPackSize;
nOutProcessSize = nTotalPackSize;
}
}
else //网络头去掉了,剩下的就是逻辑数据
{
if( pHeader->len <= nOutSize )
{
memcpy(pOutBuff,(void *)(pInBuff + i + nHeaderSize ), pHeader->len ) ;
nInProcessSize = i + nTotalPackSize;
nOutProcessSize = pHeader->len ;
}
}
if(pEncrypt)
{
pEncrypt->IncreaseCheckSum();
}
}
else
{
//OutputMsg(r)
nInProcessSize = i + nTotalPackSize; //这段数据作废
return true;
}
*/
return true;
}
void CNetworkDataHandler::FillInHeader(char *pInBuff,SIZE_T nInSize,PDATAHEADER pHeader,Encrypt * pEncrypt)
{
/*
SIZE_T nheaderSize = sizeof(DATAHEADER);
pHeader->tag = DEFAULT_TAG_VALUE;
pHeader->len = (WORD)nInSize;
//计算数据的crc
if(pEncrypt)
{
pHeader->EncodePart.hdrSum = pEncrypt->GetCheckSum();
}
else
{
pHeader->EncodePart.hdrSum = DEFAULT_HEADER_CHECK_SUM;
}
WORD nDataCrc = 0xffff & pEncrypt->CRC16((unsigned char *)pInBuff,nInSize);
pHeader->EncodePart.dataSum = nDataCrc;
//计算头部的crc
WORD nHeadCrc = 0xffff & pEncrypt->CRC16( (unsigned char *)pHeader,nheaderSize);
pHeader->EncodePart.hdrSum = nHeadCrc;
//进行加密
DATAHEADER encryptHead;
pEncrypt->Encode((char *)&pHeader->EncodePart,sizeof(&pHeader->EncodePart),(char *)&encryptHead.EncodePart);
pHeader->EncodePart = encryptHead.EncodePart;
if(pEncrypt)
{
pEncrypt->IncreaseCheckSum();
}
*/
}
INT_PTR CNetworkDataHandler::DataPack( char *pInBuff,SIZE_T nInSize, char *pOutBuff, SIZE_T nOutSize,Encrypt * pEncrypt)
{
/*
SIZE_T nheaderSize = sizeof(DATAHEADER);
if ( nOutSize < nheaderSize + nInSize ) return 0; //输出缓存长度不够
if (nInSize >65535) return 0; //最大只支持65535个字节的发送
if (m_bNeedEncrypt && pEncrypt ==NULL) return 0; //没有加密器指针
DATAHEADER head; //网络数据头
head.tag = m_nTag;
head.len = (WORD)nInSize;
head.EncodePart.hdrSum =0;
head.EncodePart.dataSum =0;
if (m_bNeedEncrypt) //如果需要加密的话。那么进行填充
{
//计算数据的crc
head.EncodePart.hdrSum = DEFAULT_HEADER_CHECK_SUM;
WORD nDataCrc = 0xffff & pEncrypt->CRC16((unsigned char *)pInBuff,nInSize);
head.EncodePart.dataSum = nDataCrc;
//计算头部的crc
WORD nHeadCrc = 0xffff & pEncrypt->CRC16( (unsigned char *)&head,nheaderSize);
head.EncodePart.hdrSum = nHeadCrc;
//进行加密
DATAHEADER encryptHead;
pEncrypt->Encode((char *)&head.EncodePart,sizeof(head.EncodePart),(char *)&encryptHead.EncodePart);
head.EncodePart = encryptHead.EncodePart;
}
memcpy((void *)pOutBuff,(void*)&head,nheaderSize); //头放进去
memcpy((void *)(pOutBuff+nheaderSize),(void*)pInBuff,nInSize); //数据放进去
return nInSize + nheaderSize;
*/
return 0;
}