📄 authsocket.cc
字号:
// AuthSocket.cc
/*/////////////////////////////////////////////////////////////////////////////
李亦
2006.06.
/*//////////////////////////////////////////////////////////////////////////////
//#include <platforms.h>
#include "platform/event.h"
#include "core/dataChunker.h"
#include "server/net/IOSocket.h"
#include "server/encrypt/EncryptEngine.h"
#include "server/net/AuthSocket.h"
#include "sim/netConnection.h"
namespace CS
{
//#include"config.h"
////////////////////////////////////////////////////////////////////////
//数据包缓冲池管理
#define PACKETQUEUE_INIT 1
#define PACKETQUEUE_GROW 32
class PacketBufPoolHandle
{
FreeListChunker<PacketBuffer> gs_pkBufPool;
MutexInstance m_mutexPool;
//PacketBufPoolHandle()
public:
PacketBuffer* alloc()
{
MutexHandle mutex(m_mutexPool,true);
return gs_pkBufPool.alloc();
}
void free(PacketBuffer* pFree)
{
MutexHandle mutex(m_mutexPool,true);
return gs_pkBufPool.free(pFree);
}
};
static PacketBufPoolHandle gs_pkBufPool;
// //
////////// Authenticated Socket Class /////////////
// //
CAuthSocket::CAuthSocket(CS_AUTHHANDLER *pHandler, CS_IOHANDLER *pIOH, CS_ENCRYPTHANDLER *pEE)
:m_queueRecv(PACKETQUEUE_INIT,PACKETQUEUE_GROW)
,m_queueSend(PACKETQUEUE_INIT,PACKETQUEUE_GROW)
{
m_pAuthHandler = pHandler;
m_pIOHandler = pIOH;
m_pEncryptHandler = pEE;
m_pEncryptEngine = NULL;
m_pIOSock = NULL;
m_pData = NULL;
m_pConnection = NULL;
m_pPacketBufRecv = NULL;
m_pPacketBufSend = NULL;
m_ssQueueSend = ASS_NULL;//默认为 TRUE
m_ssQueueRecv = ASS_NULL;
m_dwWorkState = 0;
m_netGateway.SvrListenConnection(this);
}
CAuthSocket::~CAuthSocket()
{
Close();
//if(m_pEncryptEngine != NULL)
// delete m_pEncryptEngine;
//if(m_pIOSock != NULL)
// delete m_pIOSock;
}
BOOL CAuthSocket::BeginSend(BitStream* pStream, BOOL bQueue,U8 uPacketType)
{
AssertWarn(m_pPacketBufSend==0,"在调用BeginSend之前,需要调用SendOutPacket或EndSend(true),释放 m_pPacketBufSend ");
if(pStream == NULL)
return FALSE;
U32 uSize = MaxPacketDataSize;
m_ssQueueSend = bQueue?ASS_QUEUE : ASS_SINGLE;
m_pPacketBufSend = gs_pkBufPool.alloc();
if(m_pPacketBufSend == NULL)
return FALSE;
m_pPacketBufSend->uSize = uSize;
m_pPacketBufSend->uPacketType = uPacketType;
pStream->setBuffer(m_pPacketBufSend->szBuffer, uSize, MaxPacketDataSize);
pStream->setPosition(0);
//填充识别码,U8
if(uPacketType != 0)
pStream->write(uPacketType);
return TRUE;
}
BOOL CAuthSocket::EndSend(BitStream* pStream, BOOL bProcessNow)
{
AssertWarn(m_pPacketBufSend,"包缓冲区不能为NULL");
if(pStream == NULL)
return FALSE;
if(m_pPacketBufSend == NULL)
return FALSE;
m_pPacketBufSend->uSize = pStream->getPosition();
//在EndSend中加入,因为需要等Stream填满后,才加到队列处理
//队列未满,则加到尾部
//已满,则删除头1数据包,加到尾部,打开Push的always标志即可
if(m_ssQueueSend == ASS_QUEUE)
{
m_mutexWorkState.lock(true);
m_queueSend.Push(m_pPacketBufSend);
m_mutexWorkState.unlock();
m_pPacketBufSend = NULL;
}
if(bProcessNow)
return SendOutPacket(m_ssQueueSend == ASS_QUEUE) == E_IOOK;
return TRUE;
}
S32 CAuthSocket::SendOutPacket(BOOL bQueue)
{
S32 nRet;
if(!bQueue)
{
AssertWarn(m_pPacketBufSend,"包缓冲区不能为NULL");
if(m_pPacketBufSend)
{
//if(IsAlive() && CheckSend(FALSE))
nRet = Send(m_pPacketBufSend->szBuffer, m_pPacketBufSend->uSize);
gs_pkBufPool.free(m_pPacketBufSend);
m_pPacketBufSend = NULL;
}
else
nRet = E_IOFAILED;
return nRet;
}
m_mutexWorkState.lock(true);
PacketBuffer* pPKBuf = m_queueSend.Shift();
m_mutexWorkState.unlock();
//发送到IOSocket
if(pPKBuf)
{
//if(IsAlive() && CheckSend(FALSE))
nRet = Send(pPKBuf->szBuffer, pPKBuf->uSize);
gs_pkBufPool.free(pPKBuf);
}
else
nRet = E_IOFAILED;
return nRet;
}
BOOL CAuthSocket::BeginRecv(BOOL bQueue,U8 uPacketType)
{
AssertWarn(m_pPacketBufRecv==0,"在调用BeginSend之前,需要调用ProcessRecvStream或EndRecv(true),释放 m_pPacketBufRecv ");
//if(!IsAlive() || !CheckRecv(FALSE))
// return FALSE;
U32 uSize = MaxPacketDataSize;
m_ssQueueRecv = bQueue?ASS_QUEUE : ASS_SINGLE;
m_pPacketBufRecv = gs_pkBufPool.alloc();
if(m_pPacketBufRecv == NULL)
return FALSE;
m_pPacketBufRecv->uSize = uSize;
m_pPacketBufRecv->uPacketType = uPacketType;
return TRUE;
}
BOOL CAuthSocket::EndRecv()
{
AssertWarn(m_pPacketBufRecv,"包缓冲区不能为NULL");
if(m_pPacketBufRecv == NULL )
return FALSE;
S32 nRet;
PacketBuffer* pPKBuf;
U32 uSize;
pPKBuf = m_pPacketBufRecv;
uSize = pPKBuf->uSize;
if(!uSize)
uSize = MaxPacketDataSize;
//接收到IOSocket
//调整 IOTCPModule::Recv 接收模式
nRet = Recv(pPKBuf->szBuffer,(int*)&uSize);
if(nRet == E_IOOK)
pPKBuf->uSize = uSize;
else
pPKBuf->uSize = E_IOFAILED;
if(m_ssQueueRecv == ASS_QUEUE)
{
m_mutexWorkState.lock(true);
m_queueRecv.Push(m_pPacketBufRecv);
m_mutexWorkState.unlock();
m_pPacketBufRecv = NULL;
}
return nRet == E_IOOK;
}
BOOL CAuthSocket::DispatchRecvStream(BitStream* pStream, BOOL bQueue)
{
U8 uPacketType;
S32 nRet;
PacketBuffer* pPKBuf;
U32 uSize;
AssertWarn(pStream,"Stream不能为NULL");
if(pStream == NULL)
return FALSE;
if(bQueue)
{
m_mutexWorkState.lock(true);
pPKBuf = m_queueRecv.Shift();
m_mutexWorkState.unlock();
}
else //
{
pPKBuf = m_pPacketBufRecv;
}
if(pPKBuf == NULL)
return FALSE;
uSize = pPKBuf->uSize;
if(uSize != E_IOFAILED)
{
if(!uSize)
uSize = MaxPacketDataSize;
pStream->setBuffer(pPKBuf->szBuffer, uSize, MaxPacketDataSize);
pStream->read(&uPacketType);
AssertWarn(pPKBuf->uPacketType == uPacketType,"数据包识别码不吻合...");
pPKBuf->uPacketType = uPacketType;
ProcessRecvPackets(pStream,uPacketType);
}
gs_pkBufPool.free(pPKBuf);
if(m_pPacketBufRecv != NULL)
m_pPacketBufRecv = NULL;
return uSize != E_IOFAILED;
}
BOOL CAuthSocket::ProcessRecvPackets(BitStream* pStream, U8 uPacketType)
{
switch(uPacketType)
{
case PT_GAMENORMAL:
AssertFatal(m_pConnection,"需要进行 attachConnection NetConnection接收发送数据,释放包缓存");
m_pConnection->processRawPacket(pStream);
break;
default:
return m_netGateway.ProcessRecvPackets(pStream, uPacketType);
break;
}
return TRUE;
}
BOOL CAuthSocket::BlockRecvPacket(U8 uPacketType)
{
if(BeginRecv(FALSE,uPacketType))
{
if(EndRecv())
{
BitStream stream(0,0);
return DispatchRecvStream(&stream,FALSE);
}
}
return FALSE;
}
int CAuthSocket::Listen(char *svTarget, int nUserId)
{
m_pIOSock = new CIOSocket(m_pIOHandler);
if(m_pIOSock != NULL)
{
m_pEncryptEngine=new CEncryptionEngine(m_pEncryptHandler);
if(m_pEncryptEngine != NULL)
{
if(m_pIOSock->Listen(svTarget) == E_IOOK)
{
if(m_pEncryptEngine->Startup() == E_IOOK)
{
if(m_pAuthHandler->pOnListen == NULL)
return E_IOOK;
m_pData = m_pAuthHandler->pOnListen(m_pIOSock, m_pEncryptEngine, nUserId);
if(m_pData != NULL)
return E_IOOK;
m_pEncryptEngine->Shutdown();
}//if(m_pEncryptEngine->Startup() == 0) }
m_pIOSock->Close();
}//if(m_pIOSock->Listen(svTarget) == 0)
delete m_pEncryptEngine;
m_pEncryptEngine=NULL;
}//if(m_pEncryptEngine != NULL)
delete m_pIOSock;
m_pIOSock=NULL;
}//if(m_pIOSock != NULL)
return E_IOFAILED;
}
BOOL CAuthSocket::OnAcceptParam(CAuthSocket *pAuthSockNew)
{
if(pAuthSockNew == NULL)
return FALSE;
pAuthSockNew->m_netGateway.ServerBlockSequene();
return TRUE;
}
BOOL CAuthSocket::OnConnectParam(void)
{
AssertFatal(m_pConnection,"需要指定Connection对象");
if(m_pConnection == NULL)
return FALSE;
m_netGateway.ClientBlockSequene();
return TRUE;
}
int CAuthSocket::Connect(char *svTarget, int nUserId)
{
m_pIOSock = new CIOSocket(m_pIOHandler);
if(m_pIOSock != NULL)
{
m_pEncryptEngine = new CEncryptionEngine(m_pEncryptHandler);
if(m_pEncryptEngine != NULL)
{
if(m_pIOSock->Connect(svTarget) == E_IOOK)
{
if(OnConnectParam())
{
if(m_pEncryptEngine->Startup() == E_IOOK)
{
if(m_pAuthHandler->pOnConnect == NULL)
return E_IOOK;
//建立
m_pData = m_pAuthHandler->pOnConnect(m_pIOSock, m_pEncryptEngine, nUserId);
if(m_pData != NULL)
return E_IOOK;
m_pEncryptEngine->Shutdown();
}//if(m_pEncryptEngine->Startup() == 0)
m_pIOSock->Close();
}
}//if(m_pIOSock->Connect(svTarget) == 0)
delete m_pEncryptEngine;
m_pEncryptEngine = NULL;
}//if(m_pEncryptEngine != NULL)
delete m_pIOSock;
m_pIOSock = NULL;
}//if(m_pIOSock != NULL)
return E_IOFAILED;
return E_IOOK;
}
CAuthSocket *CAuthSocket::Accept(void)
{
CIOSocket *pIOSockNew = m_pIOSock->Accept();
if(pIOSockNew != NULL)
{
CAuthSocket *pAuthSockNew;
pAuthSockNew = new CAuthSocket(m_pAuthHandler, m_pIOHandler, m_pEncryptHandler);
if(pAuthSockNew != NULL)
{
pAuthSockNew->m_pIOSock = pIOSockNew;
pAuthSockNew->m_pEncryptEngine= new CEncryptionEngine(pAuthSockNew->m_pEncryptHandler);
if(pAuthSockNew->m_pEncryptEngine != NULL)
{
if(OnAcceptParam(pAuthSockNew) )
{
if(pAuthSockNew->m_pEncryptEngine->Startup() == E_IOOK)
{
if(m_pAuthHandler->pOnAccept == NULL)
return pAuthSockNew;
pAuthSockNew->m_pData = m_pAuthHandler->pOnAccept(m_pData,
pAuthSockNew->m_pIOSock,
pAuthSockNew->m_pEncryptEngine);
if(pAuthSockNew->m_pData != NULL)
return pAuthSockNew;
pAuthSockNew->m_pEncryptEngine->Shutdown();
}//if(pAuthSockNew->m_pEncryptEngine->Startup() == 0)
}
delete pAuthSockNew->m_pEncryptEngine;
pAuthSockNew->m_pEncryptEngine=NULL;
}//if(pAuthSockNew->m_pEncryptEngine != NULL)
pAuthSockNew->m_pIOSock=NULL;
delete pAuthSockNew;
}//if(pAuthSockNew != NULL)
pIOSockNew->Close();
delete pIOSockNew;
}//if(pIOSockNew != NULL)
return NULL;
}
int CAuthSocket::Close(void)
{
if(IsKILLING())
return E_IOOK;
SetKILLING();
if(m_pConnection)
{
m_pConnection->closeConnection();
m_pConnection = NULL;
}
if(m_pIOSock)
{
m_pIOSock->Close();
delete m_pIOSock;
m_pIOSock = NULL;
}
if(m_pEncryptEngine)
{
m_pEncryptEngine->Shutdown();
delete m_pEncryptEngine;
m_pEncryptEngine = NULL;
}
if(m_pAuthHandler)
{
if(m_pAuthHandler->pOnClose && m_pData)
m_pAuthHandler->pOnClose(m_pData);
m_pAuthHandler = NULL;
}
m_pData = NULL;
#ifdef TORQUE_DEBUG
Con::printf("x 连接断开...");
#endif
return E_IOOK;
}
int CAuthSocket::Recv(BYTE *pBufRecv, int *pnInDataLen)
{
int nRet;
nRet = m_pIOSock->Recv(pBufRecv,pnInDataLen);
//AssertFatal(0,"在此检测断线状态,如下面算法");
if(nRet == E_IOOK)
return E_IOOK;
if(nRet == E_IODISCONNECTED)
SetTOBEDIE();
//if(nRet != Net::WouldBlock)
// SetTOBEDIE();
return nRet;
//{
// m_pIOSock->SaveError();
// if(m_pIOSock->HasError())
// m_pIOSock->SetKill(TRUE);
// return nRet;
//}
//if(m_pAuthHandler->pOnRecv(m_pData, m_pEncryptEngine, pBufRecv, nRecvLen, pInData, pnInDataLen) == -1)
// nRet = -1;
//return nRet;
}
int CAuthSocket::Send(BYTE *pData, int nDataLen)
{
//BYTE *pOutData;
int /*nOutDataLen,*/
nRet;
//if(m_pAuthHandler->pOnSend(m_pData, m_pEncryptEngine, pData, nDataLen, &pOutData, &nOutDataLen) == -1)
// return E_IOFAILED;
nRet = m_pIOSock->Send(pData, nDataLen);
if(nRet == E_IOOK)
return E_IOOK;
//if(nRet < 0)
{
//m_pIOSock->SaveError();
//if(m_pIOSock->HasError())
// m_pIOSock->SetKill(TRUE);
return nRet;
}
//m_pAuthHandler->pFree(m_pData, pOutData);
//return nRet;
}
int CAuthSocket::RecvEx(BYTE **pInData, int *pnInDataLen)
{
BYTE *pBufRecv;
int nRecvLen;
int nRet;
nRet = m_pIOSock->RecvEx(&pBufRecv,&nRecvLen);
//AssertFatal(0,"在此检测断线状态,如下面算法,参考Recv");
if(nRet != Net::OK)
{
if(nRet == E_IODISCONNECTED)
SetTOBEDIE();
// if(nRet != Net::WouldBlock)
// SetTOBEDIE();
return nRet;
}
//if(nRet != E_IOOK)
//{
// m_pIOSock->SaveError();
// if(m_pIOSock->HasError())
// m_pIOSock->SetKill(TRUE);
// return nRet;
//}
if(m_pAuthHandler->pOnRecv(m_pData, m_pEncryptEngine, pBufRecv, nRecvLen, pInData, pnInDataLen) == E_IOFAILED)
nRet = E_IOFAILED;
m_pIOSock->Free(pBufRecv);
return nRet;
}
int CAuthSocket::SendEx(BYTE *pData, int nDataLen)
{
BYTE *pOutData;
int nOutDataLen,
nRet;
if(m_pAuthHandler->pOnSend(m_pData, m_pEncryptEngine, pData, nDataLen, &pOutData, &nOutDataLen) == E_IOFAILED)
return E_IOFAILED;
nRet = m_pIOSock->SendEx(pOutData, nOutDataLen);
if(nRet != E_IOOK)
{
//m_pIOSock->SaveError();
//if(m_pIOSock->HasError())
// m_pIOSock->SetKill(TRUE);
return nRet;
}
m_pAuthHandler->pFree(m_pData, pOutData);
return E_IOOK;
}
void CAuthSocket::Free(BYTE *pBuffer)
{
m_pAuthHandler->pFree(m_pData, pBuffer);
}
int CAuthSocket::GetUserID(void)
{
return m_pAuthHandler->pGetUserID(m_pData);
}
CS_AUTHHANDLER *CAuthSocket::GetAuthHandler(void)
{
return m_pAuthHandler;
}
int CAuthSocket::GetRemoteAddr(char *svAddr,int nMaxLen)
{
return m_pIOSock->GetRemoteAddr(svAddr,nMaxLen);
}
int CAuthSocket::GetConnectAddr(char *svAddr, int nMaxLen)
{
return m_pIOSock->GetConnectAddr(svAddr,nMaxLen);
}
void* CAuthSocket::GetNetAddress()
{
return m_pIOSock->GetNetAddress();
}
};//namespace CS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -