Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,443 @@
|
||||
#include "stdafx.h"
|
||||
#include "ClientEventHandler.h"
|
||||
|
||||
#include <Network/Packet/PacketBase.h>
|
||||
#include <Network/Packet/PacketCommand.h>
|
||||
#include <Network/Packet/PacketStruct/ServerPacket.h>
|
||||
#include <Network/XORCrypt/XORCrypt.h>
|
||||
#include <Network/ClientNetwork/Session.h>
|
||||
#include <Utility/Compress/MiniLZO/miniLZOWrapper.h>
|
||||
#include <Thread/ThreadMgr.h>
|
||||
|
||||
#include <mmsystem.h>
|
||||
#include "GMMemory.h"
|
||||
|
||||
namespace ClientNet
|
||||
{
|
||||
|
||||
CClientEventHandler::CClientEventHandler()
|
||||
: m_lpEventHandlerMgr(0),
|
||||
m_dwHandlerID(0), m_dwSessionID(0),
|
||||
m_bCloseCalled(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CClientEventHandler::~CClientEventHandler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool CClientEventHandler::SendPacket(CNetworkMsgBlock* lpMsgBlock)
|
||||
{
|
||||
return (0 != m_lpEventHandlerMgr) ?
|
||||
m_lpEventHandlerMgr->SendPacket(this, lpMsgBlock) : false;
|
||||
}
|
||||
|
||||
CClientEventHandlerMgr::CClientEventHandlerMgr()
|
||||
: m_dwMaxEventHandlerID(0), m_bExit(FALSE)
|
||||
{
|
||||
m_SessionMgr.SetDispatchQueue(m_LockedMsgQueue);
|
||||
|
||||
CThreadMgr::Run(this);
|
||||
}
|
||||
|
||||
CClientEventHandlerMgr::~CClientEventHandlerMgr()
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Handler<65><72> <20><><EFBFBD>ؼ<EFBFBD>, Close<73><65> ȣ<><C8A3><EFBFBD>Ѵ<EFBFBD>.
|
||||
ClientEventHanderMap::iterator pos = m_ClientEventHandlerMap.begin();
|
||||
ClientEventHanderMap::iterator end = m_ClientEventHandlerMap.end();
|
||||
|
||||
for(; pos != end; ++pos)
|
||||
{
|
||||
Close(pos->second);
|
||||
}
|
||||
|
||||
// 2<>ʵ<EFBFBD><CAB5><EFBFBD> <20><><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>⸦ <20><><EFBFBD>ٸ<EFBFBD><D9B8><EFBFBD>.
|
||||
DWORD dwLastTime = timeGetTime();
|
||||
|
||||
do
|
||||
{
|
||||
HandleEvents(0xFFFFFFFF);
|
||||
Sleep(100);
|
||||
}
|
||||
while(timeGetTime() - dwLastTime < 5000 && !m_ClientEventHandlerMap.empty());
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
End();
|
||||
CThreadMgr::Stop(this, 2000);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
pos = m_ClientEventHandlerMap.begin();
|
||||
end = m_ClientEventHandlerMap.end();
|
||||
|
||||
for(; pos != end; ++pos)
|
||||
{
|
||||
delete pos->second;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CClientEventHandlerMgr::HandleEvents(unsigned long dwProcessPerCall)
|
||||
{
|
||||
m_LockedMsgQueue.GetMessages(m_LocalMsgQueue, ULONG_MAX);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><DEBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD>Ѵ<EFBFBD>.
|
||||
|
||||
CNetworkMsgBlock* lpMsgBlock = 0;
|
||||
|
||||
ClientEventHanderMap::iterator pos;
|
||||
ClientEventHanderMap::iterator end = m_ClientEventHandlerMap.end();
|
||||
|
||||
for (DWORD dwCount = 0; dwCount < dwProcessPerCall; ++dwCount)
|
||||
{
|
||||
lpMsgBlock = m_LocalMsgQueue.Dequeue();
|
||||
|
||||
if(0 == lpMsgBlock)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
pos = m_ClientEventHandlerMap.find(lpMsgBlock->GetID());
|
||||
|
||||
if(pos != end)
|
||||
{
|
||||
// <20>̹<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Handler<65><72> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̴<EFBFBD>.
|
||||
CClientEventHandler* lpHandler = pos->second;
|
||||
|
||||
switch(lpMsgBlock->GetMsgType())
|
||||
{
|
||||
case NET_MSG_ACK_DISPATCH:
|
||||
|
||||
if (-1 == lpHandler->OnDispatch(
|
||||
reinterpret_cast<PktBase*>(lpMsgBlock->rd_ptr()), lpMsgBlock->GetAddress()))
|
||||
{
|
||||
Close(lpHandler);
|
||||
}
|
||||
break;
|
||||
|
||||
case NET_MSG_ACK_OPEN:
|
||||
|
||||
{
|
||||
// <20>ɵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD> Handler<65><72> <20>̹<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
int nErrorCode = 0;
|
||||
DWORD dwSessionID = 0;
|
||||
|
||||
lpMsgBlock->pop(nErrorCode);
|
||||
lpMsgBlock->pop(dwSessionID);
|
||||
|
||||
lpHandler->SetSessionID(dwSessionID);
|
||||
if(-1 == lpHandler->OnOpen(nErrorCode))
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD> <20>ݱ⸦ ȣ<><C8A3><EFBFBD>Ѵ<EFBFBD>.
|
||||
if(0 == nErrorCode)
|
||||
{
|
||||
Close(lpHandler);
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != nErrorCode)
|
||||
{
|
||||
lpHandler->OnClose();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NET_MSG_ACK_CLOSE:
|
||||
|
||||
lpHandler->OnClose();
|
||||
|
||||
// <20>ڵ鷯<DAB5><E9B7AF> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
|
||||
delete lpHandler;
|
||||
|
||||
m_ClientEventHandlerMap.erase(pos);
|
||||
end = m_ClientEventHandlerMap.end();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO : Accept<70><74> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD>, Handler<65><72> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>. <20><><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>̰<EFBFBD><CCB0><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ְ<EFBFBD>,
|
||||
// <20><EFBFBD><DEBD><EFBFBD><EFBFBD><EFBFBD> <20>ѹ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.(CThreadEventHandler<65><72> EventID<49><44> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20>ֵ<EFBFBD><D6B5><EFBFBD>..)
|
||||
|
||||
|
||||
}
|
||||
|
||||
lpMsgBlock->SetMsgType(NET_MSG_FREE);
|
||||
CNetworkMsgPool::GetInstance().FreeNetworkMsgBlock(lpMsgBlock);
|
||||
}
|
||||
}
|
||||
|
||||
bool CClientEventHandlerMgr::Connect(INET_Addr& connAddr, CClientEventHandler* lpEventHandler)
|
||||
{
|
||||
if (0 == lpEventHandler)
|
||||
{
|
||||
fprintf(stderr, "CClientEventHandlerMgr::Connect - EventHandler is NULL\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
CNetworkMsgBlock* lpMsgBlock =
|
||||
CNetworkMsgPool::GetInstance().GetNetworkMsgBlock(1, connAddr);
|
||||
|
||||
if(0 == lpMsgBlock || !lpMsgBlock->is_valid())
|
||||
{
|
||||
fprintf(stderr, "CClientEventHandlerMgr::Connect - NetMsgBlock Create Failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD dwHandlerID = 0;
|
||||
|
||||
ClientEventHanderMap::iterator pos;
|
||||
ClientEventHanderMap::iterator end = m_ClientEventHandlerMap.end();
|
||||
|
||||
do
|
||||
{
|
||||
// <20><> <20><><EFBFBD><EFBFBD>ID<49><44> ã<>´<EFBFBD>.
|
||||
dwHandlerID = ++m_dwMaxEventHandlerID;
|
||||
pos = m_ClientEventHandlerMap.find(dwHandlerID);
|
||||
}
|
||||
while(pos != end);
|
||||
|
||||
m_ClientEventHandlerMap.insert(
|
||||
ClientEventHanderMap::value_type(dwHandlerID, lpEventHandler));
|
||||
|
||||
lpEventHandler->SetHandlerID(dwHandlerID);
|
||||
lpEventHandler->SetPeerAddress(connAddr);
|
||||
lpEventHandler->SetEventHandlerMgr(this);
|
||||
|
||||
lpMsgBlock->SetAddress(connAddr);
|
||||
lpMsgBlock->SetMsgType(NET_MSG_REQ_TCP_OPEN);
|
||||
lpMsgBlock->SetID(dwHandlerID);
|
||||
m_SessionMgr.PutMessage(lpMsgBlock);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CClientEventHandlerMgr::Close(CClientEventHandler* lpEventHandler)
|
||||
{
|
||||
CNetworkMsgBlock* lpMsgBlock =
|
||||
CNetworkMsgPool::GetInstance().GetNetworkMsgBlock(1, INET_Addr());
|
||||
|
||||
if(0 == lpMsgBlock || !lpMsgBlock->is_valid())
|
||||
{
|
||||
fprintf(stderr, "CClientEventHandlerMgr::Close - NetMsgBlock Create Failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
lpEventHandler->SetCloseCalled();
|
||||
|
||||
lpMsgBlock->SetMsgType(NET_MSG_REQ_CLOSE);
|
||||
lpMsgBlock->SetID(lpEventHandler->GetSessionID());
|
||||
m_SessionMgr.PutMessage(lpMsgBlock);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CClientEventHandlerMgr::SendPacket(CClientEventHandler* lpEventHandler, CNetworkMsgBlock* lpMsgBlock)
|
||||
{
|
||||
if (0 != lpEventHandler && 0 != lpMsgBlock)
|
||||
{
|
||||
lpMsgBlock->SetMsgType(NET_MSG_REQ_SEND);
|
||||
lpMsgBlock->SetID(lpEventHandler->GetSessionID());
|
||||
|
||||
m_SessionMgr.PutMessage(lpMsgBlock);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
unsigned int CClientEventHandlerMgr::Run()
|
||||
{
|
||||
while(!InterlockedCompareExchange(&m_bExit, TRUE, TRUE))
|
||||
{
|
||||
m_SessionMgr.HandleEvents(1000);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL CClientEventHandlerMgr::End()
|
||||
{
|
||||
InterlockedExchange(&m_bExit, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
CThreadEventHandler::CThreadEventHandler(CLockedMsgQueue& LockedMsgQueue, DWORD dwClientHandlerID)
|
||||
: m_LockedMsgQueue(LockedMsgQueue),
|
||||
m_Crypt(CXORCrypt::GetInstance()),
|
||||
m_dwClientHandlerID(dwClientHandlerID),
|
||||
CEventHandler(60) // 1<>и<EFBFBD><D0B8><EFBFBD> ȣ<><C8A3><EFBFBD>Ѵ<EFBFBD>.
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// <20><>Ŷ<EFBFBD><C5B6> <20><EFBFBD><DEBE><EFBFBD> <20><> <20>Ҹ<EFBFBD><D2B8><EFBFBD>. <20><>ü<EFBFBD><C3BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><DEBD><EFBFBD> ť<><C5A5><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
int CThreadEventHandler::OnReceived(CNetworkMsgBlock& msg_block)
|
||||
{
|
||||
const int MAX_PACKET_PER_RECV = 32;
|
||||
|
||||
char* rd_ptr = 0;
|
||||
PktBase* lpPktBase = 0;
|
||||
DWORD length = static_cast<unsigned long>(msg_block.length());
|
||||
DWORD decompress_len = 0;
|
||||
|
||||
CNetworkMsgBlock* lpNewMsgBlock = 0;
|
||||
CNetworkMsgPool& netMessagePool = CNetworkMsgPool::GetInstance();
|
||||
|
||||
CNetworkMsgQueue netMsgQueue;
|
||||
|
||||
while(sizeof(PktBase) <= length)
|
||||
{
|
||||
rd_ptr = msg_block.rd_ptr();
|
||||
lpPktBase = reinterpret_cast<PktBase*>(rd_ptr);
|
||||
|
||||
// <20><>Ŷ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> vaild<6C><64><EFBFBD><EFBFBD> Ȯ<><C8AE><EFBFBD>Ѵ<EFBFBD>. invalid<69><64> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>׳<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
if(StartBit != lpPktBase->GetStartBit())
|
||||
{
|
||||
fprintf(stderr, "CClientEventHandler::OnReceived - Packet header is invalid. Not equal startbit\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// <20><>Ŷ <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڵ<EFBFBD>
|
||||
m_Crypt.DecodeHeader(rd_ptr + 1, sizeof(PktBase) - 1, 0, 0);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
const PktBase::CMDType nPacketCMD = lpPktBase->GetCmd();
|
||||
const PktBase::LengthType nPacketLength = lpPktBase->GetLen();
|
||||
|
||||
if(length < nPacketLength)
|
||||
{
|
||||
// <20><>ü <20><>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD> <20>Ľ<EFBFBD><C4BD><EFBFBD> <20>ϱ<CFB1><E2BFA1> <20><><EFBFBD>ڶ<EFBFBD>. <20>ٽ<EFBFBD> <20><><EFBFBD>ڵ<EFBFBD> <20><> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ٸ<EFBFBD>
|
||||
m_Crypt.EncodeHeader(rd_ptr + 1, sizeof(PktBase) - 1, 0, 0);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// <20><>Ŷ <20><><EFBFBD>ڵ<EFBFBD>.
|
||||
if(lpPktBase->IsCrypt())
|
||||
{
|
||||
m_Crypt.DecodePacket(rd_ptr + sizeof(PktBase),
|
||||
nPacketLength - sizeof(PktBase), lpPktBase->GetCodePage());
|
||||
}
|
||||
|
||||
// <20><>Ŷ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
if(lpPktBase->IsCompress())
|
||||
{
|
||||
decompress_len = PktMaxLen - sizeof(PktBase);
|
||||
|
||||
lpNewMsgBlock = netMessagePool.GetNetworkMsgBlock(PktMaxLen, msg_block.GetAddress());
|
||||
if(0 == lpNewMsgBlock)
|
||||
{
|
||||
fprintf(stderr, "CClientEventHandler::OnReceived - Create NetworkMsgBlock Failed for Decompress\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char* szDecompressedPacket = lpNewMsgBlock->wr_ptr();
|
||||
memcpy(szDecompressedPacket, lpPktBase, sizeof(PktBase));
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ۿ<EFBFBD><DBBF><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
if(!CMiniLZO::Decompress(rd_ptr + sizeof(PktBase), nPacketLength - sizeof(PktBase),
|
||||
szDecompressedPacket + sizeof(PktBase), &decompress_len))
|
||||
{
|
||||
netMessagePool.FreeNetworkMsgBlock(lpNewMsgBlock);
|
||||
fprintf(stderr, "CClientEventHandler::OnReceived - Decompress Packet Failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
lpNewMsgBlock->wr_ptr(decompress_len + sizeof(PktBase));
|
||||
lpPktBase = reinterpret_cast<PktBase*>(lpNewMsgBlock->rd_ptr());
|
||||
|
||||
lpPktBase->SetLen(static_cast<PktBase::LengthType>(decompress_len + sizeof(PktBase)));
|
||||
}
|
||||
else
|
||||
{
|
||||
lpNewMsgBlock = netMessagePool.GetNetworkMsgBlock(nPacketLength, msg_block.GetAddress());
|
||||
if(0 == lpNewMsgBlock)
|
||||
{
|
||||
fprintf(stderr, "CClientEventHandler::OnReceived - Create NetworkMsgBlock Failed for Enqueue\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(lpNewMsgBlock->wr_ptr(), rd_ptr, nPacketLength);
|
||||
lpNewMsgBlock->wr_ptr(nPacketLength);
|
||||
}
|
||||
|
||||
lpNewMsgBlock->SetMsgType(NET_MSG_ACK_DISPATCH);
|
||||
lpNewMsgBlock->SetID(m_dwClientHandlerID);
|
||||
netMsgQueue.Enqueue(lpNewMsgBlock);
|
||||
|
||||
length -= nPacketLength;
|
||||
msg_block.rd_ptr(nPacketLength);
|
||||
}
|
||||
}
|
||||
|
||||
m_LockedMsgQueue.PutMessages(netMsgQueue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CThreadEventHandler::OnOpen(CSession& ConnSession, int iErrorCode)
|
||||
{
|
||||
CNetworkMsgBlock* lpNewMsgBlock =
|
||||
CNetworkMsgPool::GetInstance().GetNetworkMsgBlock(
|
||||
sizeof(int) + sizeof(unsigned long), INET_Addr());
|
||||
|
||||
if(0 == lpNewMsgBlock)
|
||||
{
|
||||
fprintf(stderr, "CThreadEventHandler::OnOpen - NetMsgBlock Create Failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
lpNewMsgBlock->SetMsgType(NET_MSG_ACK_OPEN);
|
||||
lpNewMsgBlock->SetID(m_dwClientHandlerID);
|
||||
lpNewMsgBlock->push(iErrorCode);
|
||||
lpNewMsgBlock->push(ConnSession.GetSessionID());
|
||||
|
||||
m_LockedMsgQueue.PutMessage(lpNewMsgBlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CThreadEventHandler::OnClose(CSession& CloseSession)
|
||||
{
|
||||
CNetworkMsgBlock* lpNewMsgBlock =
|
||||
CNetworkMsgPool::GetInstance().GetNetworkMsgBlock(1, INET_Addr());
|
||||
|
||||
if(0 == lpNewMsgBlock)
|
||||
{
|
||||
fprintf(stderr, "CThreadEventHandler::OnClose - NetMsgBlock Create Failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
lpNewMsgBlock->SetMsgType(NET_MSG_ACK_CLOSE);
|
||||
lpNewMsgBlock->SetID(m_dwClientHandlerID);
|
||||
m_LockedMsgQueue.PutMessage(lpNewMsgBlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CThreadEventHandler::OnTimeout(CSession& Session)
|
||||
{
|
||||
// Ping<6E><67> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
ClientNet::CNetworkMsgBlock* lpMsgBlock =
|
||||
CNetworkMsgPool::GetInstance().GetNetworkMsgBlock(sizeof(PktSyP), INET_Addr());
|
||||
|
||||
if(0 != lpMsgBlock)
|
||||
{
|
||||
PktSyP* lpSyPAckPt = reinterpret_cast<PktSyP*>(lpMsgBlock->wr_ptr());
|
||||
lpSyPAckPt->m_dwTickTime = timeGetTime();
|
||||
|
||||
if (lpMsgBlock->WrapCrypt(sizeof(PktSyP), CmdSysPing, 0))
|
||||
{
|
||||
Session.SendPending(lpMsgBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
CNetworkMsgPool::GetInstance().FreeNetworkMsgBlock(lpMsgBlock);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
#ifndef _GAMA_CLIENT_EVENT_HANDLER_DERIVED_H_
|
||||
#define _GAMA_CLIENT_EVENT_HANDLER_DERIVED_H_
|
||||
|
||||
#include <Thread/Lock.h>
|
||||
#include <Thread/Thread.h>
|
||||
#include <Network/ClientNetwork/EventHandler.h>
|
||||
#include <Network/ClientNetwork/NetworkMsgBlock.h>
|
||||
#include <Network/ClientNetwork/SessionMgr.h>
|
||||
|
||||
|
||||
#include <map>
|
||||
|
||||
// forward decl.
|
||||
struct PktBase;
|
||||
class CXORCrypt;
|
||||
|
||||
namespace ClientNet
|
||||
{
|
||||
class CSessionMgr;
|
||||
class CClientEventHandlerMgr;
|
||||
|
||||
// Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ<EFBFBD><C6AE> <20>̺<EFBFBD>Ʈ <20>ڵ鷯
|
||||
class CClientEventHandler
|
||||
{
|
||||
public:
|
||||
|
||||
CClientEventHandler();
|
||||
virtual ~CClientEventHandler();
|
||||
|
||||
virtual int OnDispatch(PktBase* lpPktBase, INET_Addr& peerAddr) = 0;
|
||||
virtual int OnOpen(int iErrorCode) = 0;
|
||||
virtual int OnClose() = 0;
|
||||
|
||||
DWORD GetHandlerID() const { return m_dwHandlerID; }
|
||||
DWORD GetSessionID() const { return m_dwSessionID; }
|
||||
|
||||
INET_Addr& GetPeerAddress() { return m_peerAddress; }
|
||||
|
||||
bool IsCloseCalled() { return m_bCloseCalled; }
|
||||
bool SendPacket(CNetworkMsgBlock* lpMsgBlock);
|
||||
|
||||
private:
|
||||
|
||||
void SetHandlerID(DWORD dwHandlerID) { m_dwHandlerID = dwHandlerID; }
|
||||
void SetSessionID(DWORD dwSessionID) { m_dwSessionID = dwSessionID; }
|
||||
void SetCloseCalled() { m_bCloseCalled = true; }
|
||||
void SetPeerAddress(INET_Addr& peerAddress) { m_peerAddress = peerAddress; }
|
||||
void SetEventHandlerMgr(CClientEventHandlerMgr* lpEventHandlerMgr) { m_lpEventHandlerMgr = lpEventHandlerMgr; }
|
||||
|
||||
CClientEventHandlerMgr* m_lpEventHandlerMgr;
|
||||
|
||||
DWORD m_dwHandlerID;
|
||||
DWORD m_dwSessionID;
|
||||
|
||||
INET_Addr m_peerAddress;
|
||||
|
||||
bool m_bCloseCalled;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> ID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ؼ<EFBFBD> <20>ʿ<EFBFBD><CABF><EFBFBD>.
|
||||
friend class CClientEventHandlerMgr;
|
||||
};
|
||||
|
||||
// Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ <20>ڵ鷯 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
class CClientEventHandlerMgr : public CThread
|
||||
{
|
||||
public:
|
||||
|
||||
CClientEventHandlerMgr();
|
||||
virtual ~CClientEventHandlerMgr();
|
||||
|
||||
bool Connect(INET_Addr& connAddr, CClientEventHandler* lpEventHandler);
|
||||
bool Close(CClientEventHandler* lpEventHandler);
|
||||
bool SendPacket(CClientEventHandler* lpEventHandler, CNetworkMsgBlock* lpMsgBlock);
|
||||
|
||||
void HandleEvents(unsigned long dwProcessPerCall);
|
||||
|
||||
private:
|
||||
|
||||
virtual unsigned int Run(); // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ´<D6B4>.
|
||||
virtual BOOL End(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>ִ<EFBFBD> <20><>ƾ<EFBFBD><C6BE> <20>ִ´<D6B4>.
|
||||
|
||||
typedef std::map<DWORD, CClientEventHandler*> ClientEventHanderMap;
|
||||
|
||||
CLockedMsgQueue m_LockedMsgQueue;
|
||||
CNetworkMsgQueue m_LocalMsgQueue;
|
||||
ClientEventHanderMap m_ClientEventHandlerMap;
|
||||
|
||||
DWORD m_dwMaxEventHandlerID;
|
||||
LONG m_bExit;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ο<EFBFBD><CEBF><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
CSessionMgr m_SessionMgr;
|
||||
};
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>̺<EFBFBD>Ʈ <20>ڵ鷯
|
||||
class CThreadEventHandler : public CEventHandler
|
||||
{
|
||||
public:
|
||||
|
||||
CThreadEventHandler(CLockedMsgQueue& LockedMsgQueue, DWORD dwClientHandlerID);
|
||||
|
||||
virtual int OnReceived(CNetworkMsgBlock& msg_block);
|
||||
virtual int OnDispatch(CSession& ReceivedSession) { return 0; }
|
||||
|
||||
virtual int OnOpen(CSession& ConnSession, int iErrorCode);
|
||||
virtual int OnClose(CSession& CloseSession);
|
||||
virtual int OnTimeout(CSession& Session);
|
||||
|
||||
private:
|
||||
|
||||
CLockedMsgQueue& m_LockedMsgQueue;
|
||||
CXORCrypt& m_Crypt;
|
||||
DWORD m_dwClientHandlerID;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifndef _GAMA_CLIENT_EVENT_HANDLER_H_
|
||||
#define _GAMA_CLIENT_EVENT_HANDLER_H_
|
||||
|
||||
namespace ClientNet
|
||||
{
|
||||
// forward decl.
|
||||
class CSession;
|
||||
class CNetworkMsgBlock;
|
||||
|
||||
class CEventHandler
|
||||
{
|
||||
public:
|
||||
|
||||
CEventHandler(DWORD dwTimeoutSec = 1)
|
||||
: m_dwTimeoutSec(dwTimeoutSec), m_dwLastCalled(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual ~CEventHandler() { }
|
||||
|
||||
virtual int OnReceived(CNetworkMsgBlock& msg_block) = 0; // <20><>Ŷ<EFBFBD><C5B6> <20><EFBFBD><DEBE><EFBFBD> <20><> <20>Ҹ<EFBFBD><D2B8><EFBFBD>.
|
||||
|
||||
virtual int OnOpen(CSession& ConnSession, int iErrorCode) = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ϸ<EFBFBD><CFB7>Ǿ<EFBFBD><C7BE><EFBFBD> <20><> <20>Ҹ<EFBFBD><D2B8><EFBFBD>. (<28><><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD>. UDP<44><50> <20>ش<EFBFBD> <20><><EFBFBD><EFBFBD>)
|
||||
virtual int OnClose(CSession& CloseSession) = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20>Ҹ<EFBFBD><D2B8><EFBFBD>. (UDP<44><50> <20>ش<EFBFBD> <20><><EFBFBD><EFBFBD>)
|
||||
virtual int OnDispatch(CSession& ReceivedSession) = 0; // <20><EFBFBD><DEBD><EFBFBD><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20><> <20>Ҹ<EFBFBD><D2B8><EFBFBD>.
|
||||
|
||||
virtual int OnTimeout(CSession& Session) = 0; // <20><><EFBFBD><EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ȣ<><C8A3><EFBFBD>ȴ<EFBFBD>. <20>⺻<EFBFBD><E2BABB> <20><><EFBFBD>ʸ<EFBFBD><CAB8><EFBFBD> <20>Ҹ<EFBFBD><D2B8><EFBFBD>.
|
||||
|
||||
bool IsTimeout(DWORD dwCurrentTime) const
|
||||
{
|
||||
return (0 == m_dwLastCalled) ||
|
||||
(m_dwLastCalled + (m_dwTimeoutSec * 1000) < dwCurrentTime);
|
||||
}
|
||||
|
||||
void UpdateTimeoutCalled(DWORD dwCurrentTime)
|
||||
{
|
||||
m_dwLastCalled = dwCurrentTime;
|
||||
if (0 == m_dwLastCalled) { ++m_dwLastCalled; }
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
DWORD m_dwTimeoutSec;
|
||||
DWORD m_dwLastCalled;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,104 @@
|
||||
#include "stdafx.h"
|
||||
#include "MessageBlock.h"
|
||||
#include <xmemory>
|
||||
#include "GMMemory.h"
|
||||
|
||||
CMessageBlock::CMessageBlock()
|
||||
: internal_buffer_(0), rd_ptr_(0), wr_ptr_(0), buffer_size_(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CMessageBlock::CMessageBlock(size_t n)
|
||||
: internal_buffer_(0), rd_ptr_(0), wr_ptr_(0), buffer_size_(0)
|
||||
{
|
||||
init(n);
|
||||
}
|
||||
|
||||
CMessageBlock::~CMessageBlock()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
bool CMessageBlock::init(size_t n)
|
||||
{
|
||||
if(buffer_size_ < n)
|
||||
{
|
||||
destroy();
|
||||
internal_buffer_ = new char[n];
|
||||
}
|
||||
|
||||
rd_ptr_ = wr_ptr_ = internal_buffer_;
|
||||
buffer_size_ = n;
|
||||
|
||||
return (0 != internal_buffer_);
|
||||
}
|
||||
|
||||
void CMessageBlock::destroy()
|
||||
{
|
||||
if(NULL != internal_buffer_)
|
||||
{
|
||||
delete [] internal_buffer_;
|
||||
}
|
||||
|
||||
buffer_size_ = 0;
|
||||
rd_ptr_ = wr_ptr_ = internal_buffer_ = 0;
|
||||
}
|
||||
|
||||
bool CMessageBlock::push(const void* ptr, size_t n)
|
||||
{
|
||||
if(NULL != wr_ptr_ && n <= capacity() - length())
|
||||
{
|
||||
memcpy(wr_ptr_, ptr, n);
|
||||
wr_ptr_ += n;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CMessageBlock::pop_read_data()
|
||||
{
|
||||
if(NULL != internal_buffer_)
|
||||
{
|
||||
size_t n = length();
|
||||
memmove(internal_buffer_, rd_ptr_, n);
|
||||
wr_ptr_ = internal_buffer_ + n;
|
||||
rd_ptr_ = internal_buffer_;
|
||||
}
|
||||
}
|
||||
|
||||
CMessageBlock* CMessageBlock::clone(CMessageBlock& msg_block)
|
||||
{
|
||||
CMessageBlock* lpMessageBlock = new CMessageBlock(msg_block.length());
|
||||
|
||||
if(NULL != lpMessageBlock)
|
||||
{
|
||||
memcpy(lpMessageBlock->wr_ptr(), msg_block.rd_ptr(), msg_block.length());
|
||||
lpMessageBlock->wr_ptr(msg_block.length());
|
||||
return lpMessageBlock;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool CMessageBlock::resize(size_t n)
|
||||
{
|
||||
char* temp_buffer = new char[n];
|
||||
|
||||
if(NULL != temp_buffer)
|
||||
{
|
||||
memcpy(temp_buffer, internal_buffer_,
|
||||
(buffer_size_ < n) ? n : buffer_size_);
|
||||
|
||||
rd_ptr_ = temp_buffer + (rd_ptr_ - internal_buffer_);
|
||||
wr_ptr_ = temp_buffer + (wr_ptr_ - internal_buffer_);
|
||||
std::swap(internal_buffer_,temp_buffer);
|
||||
|
||||
delete [] temp_buffer;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
#ifndef _CLIENTSOCKET_MESSAGE_BLOCK_H_
|
||||
#define _CLIENTSOCKET_MESSAGE_BLOCK_H_
|
||||
|
||||
class CMessageBlock
|
||||
{
|
||||
public:
|
||||
|
||||
explicit CMessageBlock();
|
||||
explicit CMessageBlock(size_t n);
|
||||
virtual ~CMessageBlock();
|
||||
|
||||
bool is_valid() { return 0 != internal_buffer_; }
|
||||
|
||||
// <20>б<EFBFBD> - <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
char* rd_ptr() const { return rd_ptr_; }
|
||||
void rd_ptr(size_t n) { rd_ptr_ += n; }
|
||||
void rd_ptr(char* ptr) { rd_ptr_ = ptr; }
|
||||
|
||||
char* wr_ptr() const { return wr_ptr_; }
|
||||
void wr_ptr(size_t n) { wr_ptr_ += n; }
|
||||
void wr_ptr(char* ptr) { wr_ptr_ = ptr; }
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(past-end) <20><> <20><><EFBFBD><EFBFBD>.
|
||||
char* begin() const { return internal_buffer_; }
|
||||
char* end() const { return internal_buffer_ + buffer_size_; }
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>۷<EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
bool push(const void* ptr, size_t n);
|
||||
|
||||
template<typename T>
|
||||
bool push(const T& t)
|
||||
{
|
||||
if(0 != wr_ptr_ && sizeof(T) <= capacity() - length())
|
||||
{
|
||||
memcpy(wr_ptr_, &t, sizeof(T));
|
||||
wr_ptr_ += sizeof(T);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool pop(T& t)
|
||||
{
|
||||
if(0 != rd_ptr_ && sizeof(T) <= length())
|
||||
{
|
||||
memcpy(&t, rd_ptr_, sizeof(T));
|
||||
rd_ptr_ += sizeof(T);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// <20>̹<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><> <20><><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD> <20><>ȿȭ<C8BF><C8AD>.
|
||||
void pop_read_data();
|
||||
|
||||
size_t length() const { return wr_ptr_ - rd_ptr_; } // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
size_t capacity() const { return buffer_size_; } // <20><><EFBFBD><EFBFBD> ũ<><C5A9>
|
||||
size_t remain() const { return internal_buffer_ + buffer_size_ - wr_ptr_; } // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20>ڽ<EFBFBD><DABD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
static CMessageBlock* clone(CMessageBlock& msg_block);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> ũ<>⸦ <20>ø<EFBFBD><C3B8><EFBFBD>.
|
||||
bool resize(size_t n);
|
||||
|
||||
// <20>ʱ<EFBFBD>ȭ
|
||||
bool init(size_t n);
|
||||
|
||||
private:
|
||||
|
||||
void destroy();
|
||||
|
||||
char* internal_buffer_;
|
||||
char* rd_ptr_;
|
||||
char* wr_ptr_;
|
||||
size_t buffer_size_;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,543 @@
|
||||
#include "stdafx.h"
|
||||
#include "NetworkMsgBlock.h"
|
||||
#include <Network/Packet/PacketBase.h>
|
||||
#include <Network/XORCrypt/XORCrypt.h>
|
||||
#include <Utility/Compress/MiniLZO/miniLZOWrapper.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include "GMMemory.h"
|
||||
|
||||
|
||||
namespace ClientNet
|
||||
{
|
||||
|
||||
CNetworkMsgBlock::CNetworkMsgBlock(size_t n)
|
||||
: CMessageBlock(n), m_next(0),
|
||||
m_eMsgType(NET_MSG_FREE), m_dwID(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CNetworkMsgBlock::CNetworkMsgBlock(size_t n, INET_Addr& addr)
|
||||
: CMessageBlock(n), m_dstaddr(addr), m_next(0),
|
||||
m_eMsgType(NET_MSG_FREE), m_dwID(0)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
CNetworkMsgBlock::~CNetworkMsgBlock()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool CNetworkMsgBlock::WrapHeader(unsigned short usUsed_In, unsigned char cCMD_In,
|
||||
unsigned short usState_In, unsigned short usError_In)
|
||||
{
|
||||
char* lpBuffer = rd_ptr();
|
||||
|
||||
if(NULL != lpBuffer && sizeof(PktBase) <= usUsed_In && usUsed_In <= remain())
|
||||
{
|
||||
reinterpret_cast<PktBase*>(lpBuffer)->InitPtHead(usUsed_In, cCMD_In, usState_In, usError_In);
|
||||
CXORCrypt::GetInstance().EncodeHeader(lpBuffer + 1, sizeof(PktBase) - 1, 0, 0);
|
||||
|
||||
wr_ptr(usUsed_In);
|
||||
return true;
|
||||
}
|
||||
|
||||
fprintf(stderr, "CNetworkMsgBlock::WrapHeader - Packet wrapping error. CMD:0x%02x, usUsed:%d, capacity:%d\n",
|
||||
cCMD_In, usUsed_In, capacity());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CNetworkMsgBlock::WrapCryptOld(unsigned short usUsed_In, unsigned char cCMD_In,
|
||||
unsigned long Tick_In)
|
||||
{
|
||||
char* lpBuffer = rd_ptr();
|
||||
|
||||
if(NULL != lpBuffer && sizeof(PktBase) <= usUsed_In && usUsed_In <= remain())
|
||||
{
|
||||
CXORCrypt& Crypt = CXORCrypt::GetInstance();
|
||||
DWORD dwCodePage = Crypt.GetCodePage(1);
|
||||
|
||||
if(Crypt.EncodePacket(lpBuffer + sizeof(PktBase), usUsed_In - sizeof(PktBase), dwCodePage))
|
||||
{
|
||||
PktBase* lpPktBase = reinterpret_cast<PktBase*>(lpBuffer);
|
||||
|
||||
lpPktBase->InitPtHead(usUsed_In, cCMD_In, Tick_In);
|
||||
lpPktBase->SetCodePage(dwCodePage);
|
||||
lpPktBase->SetCrypt();
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڵ<EFBFBD>
|
||||
Crypt.EncodeHeader(lpBuffer + 1, sizeof(PktBase) - 1, 0, 0);
|
||||
|
||||
wr_ptr(usUsed_In);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "CNetworkMsgBlock::WrapCrypt - Packet wrapping error. CMD:0x%02x, usUsed:%d, capacity:%d\n",
|
||||
cCMD_In, usUsed_In, capacity());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CNetworkMsgBlock::WrapCryptOld(unsigned short usUsed_In, unsigned char cCMD_In,
|
||||
unsigned short usState_In, unsigned short usError_In)
|
||||
{
|
||||
char* lpBuffer = rd_ptr();
|
||||
|
||||
if(NULL != lpBuffer && sizeof(PktBase) <= usUsed_In && usUsed_In <= remain())
|
||||
{
|
||||
CXORCrypt& Crypt = CXORCrypt::GetInstance();
|
||||
DWORD dwCodePage = Crypt.GetCodePage(1);
|
||||
|
||||
if(Crypt.EncodePacket(lpBuffer + sizeof(PktBase), usUsed_In - sizeof(PktBase), dwCodePage))
|
||||
{
|
||||
PktBase* lpPktBase = reinterpret_cast<PktBase*>(lpBuffer);
|
||||
|
||||
lpPktBase->InitPtHead(usUsed_In, cCMD_In, usState_In, usError_In);
|
||||
lpPktBase->SetCodePage(dwCodePage);
|
||||
lpPktBase->SetCrypt();
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڵ<EFBFBD>
|
||||
Crypt.EncodeHeader(lpBuffer + 1, sizeof(PktBase) - 1, 0, 0);
|
||||
|
||||
wr_ptr(usUsed_In);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "CNetworkMsgBlock::WrapCrypt - Packet wrapping error. CMD:0x%02x, usUsed:%d, capacity:%d\n",
|
||||
cCMD_In, usUsed_In, capacity());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CNetworkMsgBlock::WrapCrypt(unsigned short usUsed_In, unsigned char cCMD_In,
|
||||
unsigned long Tick_In)
|
||||
{
|
||||
char* lpBuffer = rd_ptr();
|
||||
|
||||
if(NULL != lpBuffer && sizeof(PktBase) <= usUsed_In && usUsed_In <= remain())
|
||||
{
|
||||
CXORCrypt& Crypt = CXORCrypt::GetInstance();
|
||||
DWORD dwCodePage = Crypt.GetCodePage();
|
||||
|
||||
if(Crypt.EncodePacket(lpBuffer + sizeof(PktBase), usUsed_In - sizeof(PktBase), dwCodePage))
|
||||
{
|
||||
PktBase* lpPktBase = reinterpret_cast<PktBase*>(lpBuffer);
|
||||
|
||||
lpPktBase->InitPtHead(usUsed_In, cCMD_In, Tick_In);
|
||||
lpPktBase->SetCodePage(dwCodePage);
|
||||
lpPktBase->SetCrypt();
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڵ<EFBFBD>
|
||||
Crypt.EncodeHeader(lpBuffer + 1, sizeof(PktBase) - 1, 0, 0);
|
||||
|
||||
wr_ptr(usUsed_In);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "CNetworkMsgBlock::WrapCrypt - Packet wrapping error. CMD:0x%02x, usUsed:%d, capacity:%d\n",
|
||||
cCMD_In, usUsed_In, capacity());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CNetworkMsgBlock::WrapCrypt(unsigned short usUsed_In, unsigned char cCMD_In,
|
||||
unsigned short usState_In, unsigned short usError_In)
|
||||
{
|
||||
char* lpBuffer = rd_ptr();
|
||||
|
||||
if(NULL != lpBuffer && sizeof(PktBase) <= usUsed_In && usUsed_In <= remain())
|
||||
{
|
||||
CXORCrypt& Crypt = CXORCrypt::GetInstance();
|
||||
DWORD dwCodePage = Crypt.GetCodePage();
|
||||
|
||||
if(Crypt.EncodePacket(lpBuffer + sizeof(PktBase), usUsed_In - sizeof(PktBase), dwCodePage))
|
||||
{
|
||||
PktBase* lpPktBase = reinterpret_cast<PktBase*>(lpBuffer);
|
||||
|
||||
lpPktBase->InitPtHead(usUsed_In, cCMD_In, usState_In, usError_In);
|
||||
lpPktBase->SetCodePage(dwCodePage);
|
||||
lpPktBase->SetCrypt();
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڵ<EFBFBD>
|
||||
Crypt.EncodeHeader(lpBuffer + 1, sizeof(PktBase) - 1, 0, 0);
|
||||
|
||||
wr_ptr(usUsed_In);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "CNetworkMsgBlock::WrapCrypt - Packet wrapping error. CMD:0x%02x, usUsed:%d, capacity:%d\n",
|
||||
cCMD_In, usUsed_In, capacity());
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned long CNetworkMsgBlock::GetMinCompressSize(unsigned short usSourceLength)
|
||||
{
|
||||
return usSourceLength + (usSourceLength / 64) + 16 + 3;
|
||||
}
|
||||
|
||||
bool CNetworkMsgBlock::WrapCompress(char* lpSourceData, unsigned short usSourceLength,
|
||||
unsigned char cCMD_In, unsigned short usState_In,
|
||||
unsigned short usError_In)
|
||||
{
|
||||
unsigned long dwDstBufferSize = static_cast<unsigned long>(remain());
|
||||
|
||||
if(usSourceLength < sizeof(PktBase) || PktMaxLen < usSourceLength)
|
||||
{
|
||||
fprintf(stderr, "CNetworkMsgBlock::WrapCompress - Packet wrapping error. CMD:0x%02x, usSourceLength:%d, dwDstBufferSize:%d\n",
|
||||
cCMD_In, usSourceLength, dwDstBufferSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dwDstBufferSize < sizeof(PktBase) || dwDstBufferSize < GetMinCompressSize(usSourceLength))
|
||||
{
|
||||
fprintf(stderr, "CNetworkMsgBlock::WrapCompress - Too small buffer size. CMD:0x%02x, usSourceLength:%d, dwDstBufferSize:%d\n",
|
||||
cCMD_In, usSourceLength, dwDstBufferSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
char* lpDstBuffer = rd_ptr();
|
||||
unsigned long dwCompressedSize = dwDstBufferSize - sizeof(PktBase);
|
||||
|
||||
if(!CMiniLZO::Compress(lpSourceData + sizeof(PktBase), usSourceLength - sizeof(PktBase),
|
||||
lpDstBuffer + sizeof(PktBase), &dwCompressedSize))
|
||||
{
|
||||
fprintf(stderr, "CNetworkMsgBlock::WrapCompress - Packet Compress failed. CMD:0x%02x, usSourceLength:%d, "
|
||||
"dwDstBufferSize:%d\n", cCMD_In, usSourceLength, dwDstBufferSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dwDstBufferSize <= dwCompressedSize)
|
||||
{
|
||||
fprintf(stderr, "CNetworkMsgBlock::WrapCompress - Compressed size is over than buffer size."
|
||||
"CMD:0x%02x, dwDstBufferSize:%d, dwCompressedSize:%d\n", cCMD_In, dwDstBufferSize, dwCompressedSize);
|
||||
}
|
||||
|
||||
dwCompressedSize += sizeof(PktBase);
|
||||
|
||||
PktBase* lpPktDst = reinterpret_cast<PktBase*>(lpDstBuffer);
|
||||
lpPktDst->InitPtHead(static_cast<PktBase::LengthType>(dwCompressedSize), cCMD_In, usState_In, usError_In);
|
||||
lpPktDst->SetCompress();
|
||||
|
||||
// <20><><EFBFBD>ڵ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
CXORCrypt::GetInstance().EncodeHeader(lpDstBuffer + 1, sizeof(PktBase) - 1, 0, 0);
|
||||
|
||||
wr_ptr(dwCompressedSize);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
CNetworkMsgQueue::CNetworkMsgQueue()
|
||||
: m_lpListHead(NULL), m_lpListTail(NULL), m_nListNum(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CNetworkMsgQueue::~CNetworkMsgQueue()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void CNetworkMsgQueue::clear()
|
||||
{
|
||||
CNetworkMsgPool::GetInstance().FreeNetworkMsgBlock(*this);
|
||||
}
|
||||
|
||||
void CNetworkMsgQueue::Enqueue(CNetworkMsgBlock* lpMsgBlock, bool bPendHead)
|
||||
{
|
||||
if(NULL != lpMsgBlock)
|
||||
{
|
||||
if(m_lpListHead == NULL)
|
||||
{
|
||||
m_lpListHead = m_lpListTail = lpMsgBlock;
|
||||
lpMsgBlock->next(NULL);
|
||||
}
|
||||
else if(!bPendHead)
|
||||
{
|
||||
m_lpListTail->next(lpMsgBlock);
|
||||
m_lpListTail = lpMsgBlock;
|
||||
lpMsgBlock->next(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
lpMsgBlock->next(m_lpListHead);
|
||||
m_lpListHead = lpMsgBlock;
|
||||
}
|
||||
|
||||
++m_nListNum;
|
||||
}
|
||||
}
|
||||
|
||||
CNetworkMsgBlock* CNetworkMsgQueue::Dequeue()
|
||||
{
|
||||
CNetworkMsgBlock* lpMsgBlock = NULL;
|
||||
|
||||
if(m_lpListTail != NULL)
|
||||
{
|
||||
lpMsgBlock = m_lpListHead;
|
||||
m_lpListHead = m_lpListHead->next();
|
||||
|
||||
if(m_lpListTail == lpMsgBlock)
|
||||
{
|
||||
m_lpListTail = NULL;
|
||||
}
|
||||
|
||||
lpMsgBlock->next(NULL);
|
||||
--m_nListNum;
|
||||
}
|
||||
|
||||
return lpMsgBlock;
|
||||
}
|
||||
|
||||
|
||||
CNetworkMsgBlock* CNetworkMsgPool::GetNetworkMsgBlock(unsigned long dwSize, INET_Addr& addr)
|
||||
{
|
||||
MsgBlockLock::Syncronize sync(m_MsgBlockLock);
|
||||
|
||||
CNetworkMsgBlock* lpMsgBlock = 0;
|
||||
|
||||
if (m_MsgBlockList.empty())
|
||||
{
|
||||
lpMsgBlock = new CNetworkMsgBlock(dwSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
lpMsgBlock = m_MsgBlockList.front();
|
||||
m_MsgBlockList.pop_front();
|
||||
|
||||
if (0 != lpMsgBlock)
|
||||
{
|
||||
lpMsgBlock->init(dwSize);
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != lpMsgBlock && lpMsgBlock->is_valid()
|
||||
&& dwSize <= lpMsgBlock->capacity())
|
||||
{
|
||||
return lpMsgBlock;
|
||||
}
|
||||
|
||||
delete lpMsgBlock;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CNetworkMsgPool::FreeNetworkMsgBlock(CNetworkMsgBlock* lpMsgBlock)
|
||||
{
|
||||
MsgBlockLock::Syncronize sync(m_MsgBlockLock);
|
||||
|
||||
if (0 != lpMsgBlock)
|
||||
{
|
||||
if (m_MsgBlockList.size() < m_dwMaxBlockNum)
|
||||
{
|
||||
m_MsgBlockList.push_back(lpMsgBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete lpMsgBlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CNetworkMsgPool::FreeNetworkMsgBlock(CNetworkMsgQueue& msgQueue)
|
||||
{
|
||||
MsgBlockLock::Syncronize sync(m_MsgBlockLock);
|
||||
|
||||
CNetworkMsgBlock* lpMsgBlock = 0;
|
||||
|
||||
while (0 != (lpMsgBlock = msgQueue.Dequeue()))
|
||||
{
|
||||
if (m_MsgBlockList.size() < m_dwMaxBlockNum)
|
||||
{
|
||||
m_MsgBlockList.push_back(lpMsgBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete lpMsgBlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CNetworkMsgPool& CNetworkMsgPool::GetInstance()
|
||||
{
|
||||
static CNetworkMsgPool msgPool;
|
||||
return msgPool;
|
||||
}
|
||||
|
||||
CNetworkMsgPool::CNetworkMsgPool()
|
||||
: m_dwMaxBlockNum(50)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CNetworkMsgPool::~CNetworkMsgPool()
|
||||
{
|
||||
MsgBlockLock::Syncronize sync(m_MsgBlockLock);
|
||||
|
||||
MsgBlockList::iterator pos = m_MsgBlockList.begin();
|
||||
MsgBlockList::iterator end = m_MsgBlockList.end();
|
||||
|
||||
for(; pos != end; ++pos)
|
||||
{
|
||||
delete *pos;
|
||||
}
|
||||
|
||||
m_MsgBlockList.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
CLockedMsgQueue::~CLockedMsgQueue()
|
||||
{
|
||||
MsgQueueLock::Syncronize sync(m_MsgQueueLock);
|
||||
m_MessageQueue.clear();
|
||||
}
|
||||
|
||||
CNetworkMsgBlock* CLockedMsgQueue::GetMessage()
|
||||
{
|
||||
MsgQueueLock::Syncronize sync(m_MsgQueueLock);
|
||||
return m_MessageQueue.Dequeue();
|
||||
}
|
||||
|
||||
|
||||
void CLockedMsgQueue::GetMessages(CNetworkMsgQueue& msgQueue, DWORD dwItemNum)
|
||||
{
|
||||
CNetworkMsgBlock* lpMsg = 0;
|
||||
|
||||
MsgQueueLock::Syncronize sync(m_MsgQueueLock);
|
||||
|
||||
for(DWORD dwCount = 0; dwCount < dwItemNum; ++dwCount)
|
||||
{
|
||||
if(0 != (lpMsg = m_MessageQueue.Dequeue()))
|
||||
{
|
||||
msgQueue.Enqueue(lpMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CLockedMsgQueue::PutMessage(CNetworkMsgBlock* lpMsg, bool bPendHead)
|
||||
{
|
||||
MsgQueueLock::Syncronize sync(m_MsgQueueLock);
|
||||
m_MessageQueue.Enqueue(lpMsg, bPendHead);
|
||||
}
|
||||
|
||||
void CLockedMsgQueue::PutMessages(CNetworkMsgQueue& msgQueue)
|
||||
{
|
||||
CNetworkMsgBlock* lpMsg = 0;
|
||||
|
||||
MsgQueueLock::Syncronize sync(m_MsgQueueLock);
|
||||
while(0 != (lpMsg = msgQueue.Dequeue()))
|
||||
{
|
||||
m_MessageQueue.Enqueue(lpMsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CUnboundedWaitableMsgQueue::CUnboundedWaitableMsgQueue()
|
||||
{
|
||||
// Create Auto-Reset Event
|
||||
m_hNotEmpty = CreateEvent(0, FALSE, FALSE, 0);
|
||||
}
|
||||
|
||||
CUnboundedWaitableMsgQueue::~CUnboundedWaitableMsgQueue()
|
||||
{
|
||||
CloseHandle(m_hNotEmpty);
|
||||
}
|
||||
|
||||
DWORD CUnboundedWaitableMsgQueue::WaitForNotEmptyQueue(DWORD dwMilliseconds)
|
||||
{
|
||||
return WaitForSingleObject(m_hNotEmpty, dwMilliseconds);
|
||||
}
|
||||
|
||||
CNetworkMsgBlock* CUnboundedWaitableMsgQueue::GetMessage()
|
||||
{
|
||||
MsgQueueLock::Syncronize sync(m_MsgQueueLock);
|
||||
CNetworkMsgBlock* lpMsg = m_MessageQueue.Dequeue();
|
||||
|
||||
InternalResetNotEmpty();
|
||||
|
||||
return lpMsg;
|
||||
}
|
||||
|
||||
void CUnboundedWaitableMsgQueue::GetMessages(CNetworkMsgQueue& msgQueue, DWORD dwItemNum)
|
||||
{
|
||||
CNetworkMsgBlock* lpMsg = 0;
|
||||
|
||||
MsgQueueLock::Syncronize sync(m_MsgQueueLock);
|
||||
|
||||
for(DWORD dwCount = 0; dwCount < dwItemNum; ++dwCount)
|
||||
{
|
||||
if(0 != (lpMsg = m_MessageQueue.Dequeue()))
|
||||
{
|
||||
msgQueue.Enqueue(lpMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
InternalResetNotEmpty();
|
||||
}
|
||||
|
||||
void CUnboundedWaitableMsgQueue::PutMessage(CNetworkMsgBlock* lpMsg, bool bPendHead)
|
||||
{
|
||||
MsgQueueLock::Syncronize sync(m_MsgQueueLock);
|
||||
m_MessageQueue.Enqueue(lpMsg, bPendHead);
|
||||
|
||||
InternalSetNotEmpty();
|
||||
}
|
||||
|
||||
void CUnboundedWaitableMsgQueue::PutMessages(CNetworkMsgQueue& msgQueue)
|
||||
{
|
||||
CNetworkMsgBlock* lpMsg = 0;
|
||||
|
||||
MsgQueueLock::Syncronize sync(m_MsgQueueLock);
|
||||
while(0 != (lpMsg = msgQueue.Dequeue()))
|
||||
{
|
||||
m_MessageQueue.Enqueue(lpMsg);
|
||||
}
|
||||
|
||||
InternalSetNotEmpty();
|
||||
}
|
||||
|
||||
void CUnboundedWaitableMsgQueue::InternalSetNotEmpty()
|
||||
{
|
||||
if(!m_bNotEmpty && 0 != m_MessageQueue.GetQueuedNum())
|
||||
{
|
||||
SetEvent(m_hNotEmpty); m_bNotEmpty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void CUnboundedWaitableMsgQueue::InternalResetNotEmpty()
|
||||
{
|
||||
if(m_bNotEmpty && 0 == m_MessageQueue.GetQueuedNum())
|
||||
{
|
||||
ResetEvent(m_hNotEmpty);
|
||||
m_bNotEmpty = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
#ifndef _GAMA_CLIENT_NETWORK_BLOCK_MSG_
|
||||
#define _GAMA_CLIENT_NETWORK_BLOCK_MSG_
|
||||
|
||||
#include <Thread/Lock.h>
|
||||
#include <Network/Address/INET_Addr.h>
|
||||
#include "MessageBlock.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace ClientNet
|
||||
{
|
||||
enum NetMsgType
|
||||
{
|
||||
NET_MSG_FREE,
|
||||
NET_MSG_ACK_OPEN,
|
||||
NET_MSG_ACK_CLOSE,
|
||||
NET_MSG_ACK_DISPATCH,
|
||||
|
||||
NET_MSG_REQ_TCP_OPEN,
|
||||
NET_MSG_REQ_UDP_OPEN,
|
||||
NET_MSG_REQ_CLOSE,
|
||||
NET_MSG_REQ_SEND
|
||||
};
|
||||
|
||||
// Network Message Block
|
||||
class CNetworkMsgBlock : public CMessageBlock
|
||||
{
|
||||
public:
|
||||
|
||||
void SetMsgType(NetMsgType eMsgType) { m_eMsgType = eMsgType; }
|
||||
NetMsgType GetMsgType() const { return m_eMsgType; }
|
||||
|
||||
void SetID(DWORD dwID) { m_dwID = dwID; }
|
||||
DWORD GetID() const { return m_dwID; }
|
||||
|
||||
INET_Addr& GetAddress() { return m_dstaddr; }
|
||||
void SetAddress(INET_Addr& addr) { m_dstaddr = addr; }
|
||||
|
||||
bool WrapHeader(unsigned short usUsed_In, unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In);
|
||||
bool WrapCryptOld(unsigned short usUsed_In, unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In);
|
||||
bool WrapCryptOld(unsigned short usUsed_In, unsigned char cCMD_In, unsigned long Tick_In);
|
||||
bool WrapCrypt(unsigned short usUsed_In, unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In);
|
||||
bool WrapCrypt(unsigned short usUsed_In, unsigned char cCMD_In, unsigned long Tick_In);
|
||||
bool WrapCompress(char* lpSourceData, unsigned short usSourceLength, unsigned char cCMD_In, unsigned short usState_In, unsigned short usError_In);
|
||||
|
||||
static unsigned long GetMinCompressSize(unsigned short usSourceLength);
|
||||
CNetworkMsgBlock* next() { return m_next; }
|
||||
|
||||
private:
|
||||
|
||||
void next(CNetworkMsgBlock* next) { m_next = next; }
|
||||
|
||||
explicit CNetworkMsgBlock(size_t n);
|
||||
explicit CNetworkMsgBlock(size_t n, INET_Addr& addr);
|
||||
virtual ~CNetworkMsgBlock();
|
||||
|
||||
INET_Addr m_dstaddr;
|
||||
NetMsgType m_eMsgType;
|
||||
DWORD m_dwID;
|
||||
CNetworkMsgBlock* m_next;
|
||||
|
||||
friend class CSession;
|
||||
friend class CNetworkMsgQueue;
|
||||
friend class CNetworkMsgPool;
|
||||
};
|
||||
|
||||
// Network Message Queue
|
||||
class CNetworkMsgQueue
|
||||
{
|
||||
public:
|
||||
|
||||
CNetworkMsgQueue();
|
||||
~CNetworkMsgQueue();
|
||||
|
||||
void clear();
|
||||
|
||||
CNetworkMsgBlock* GetHead() { return m_lpListHead; }
|
||||
CNetworkMsgBlock* GetTail() { return m_lpListTail; }
|
||||
long GetQueuedNum() { return m_nListNum; }
|
||||
|
||||
void Enqueue(CNetworkMsgBlock* lpMsgBlock, bool bPendHead = false);
|
||||
CNetworkMsgBlock* Dequeue();
|
||||
|
||||
private:
|
||||
|
||||
CNetworkMsgBlock* m_lpListHead;
|
||||
CNetworkMsgBlock* m_lpListTail;
|
||||
long m_nListNum;
|
||||
};
|
||||
|
||||
class CNetworkMsgPool
|
||||
{
|
||||
public:
|
||||
|
||||
static CNetworkMsgPool& GetInstance();
|
||||
|
||||
CNetworkMsgBlock* GetNetworkMsgBlock(unsigned long dwSize, INET_Addr& addr);
|
||||
void FreeNetworkMsgBlock(CNetworkMsgBlock* lpMsgBlock);
|
||||
void FreeNetworkMsgBlock(CNetworkMsgQueue& msgQueue);
|
||||
|
||||
private:
|
||||
|
||||
CNetworkMsgPool();
|
||||
~CNetworkMsgPool();
|
||||
|
||||
typedef CCSLock MsgBlockLock;
|
||||
typedef std::list<CNetworkMsgBlock*> MsgBlockList;
|
||||
|
||||
MsgBlockLock m_MsgBlockLock;
|
||||
MsgBlockList m_MsgBlockList;
|
||||
|
||||
DWORD m_dwMaxBlockNum;
|
||||
};
|
||||
|
||||
class CLockedMsgQueue
|
||||
{
|
||||
public:
|
||||
|
||||
typedef CCSLock MsgQueueLock;
|
||||
|
||||
virtual ~CLockedMsgQueue();
|
||||
|
||||
CNetworkMsgBlock* GetMessage();
|
||||
void GetMessages(CNetworkMsgQueue& msgQueue, DWORD dwItemNum);
|
||||
|
||||
void PutMessage(CNetworkMsgBlock* lpMsg, bool bPendHead = false);
|
||||
void PutMessages(CNetworkMsgQueue& msgQueue);
|
||||
|
||||
private:
|
||||
|
||||
MsgQueueLock m_MsgQueueLock;
|
||||
CNetworkMsgQueue m_MessageQueue;
|
||||
};
|
||||
|
||||
class CUnboundedWaitableMsgQueue
|
||||
{
|
||||
public:
|
||||
|
||||
typedef CCSLock MsgQueueLock;
|
||||
|
||||
CUnboundedWaitableMsgQueue();
|
||||
virtual ~CUnboundedWaitableMsgQueue();
|
||||
|
||||
const HANDLE GetQueueHandle() const { return m_hNotEmpty; }
|
||||
DWORD WaitForNotEmptyQueue(DWORD dwMilliseconds = INFINITE);
|
||||
|
||||
CNetworkMsgBlock* GetMessage();
|
||||
void GetMessages(CNetworkMsgQueue& msgQueue, DWORD dwItemNum);
|
||||
|
||||
void PutMessage(CNetworkMsgBlock* lpMsg, bool bPendHead = false);
|
||||
void PutMessages(CNetworkMsgQueue& msgQueue);
|
||||
|
||||
private:
|
||||
|
||||
void InternalSetNotEmpty();
|
||||
void InternalResetNotEmpty();
|
||||
|
||||
HANDLE m_hNotEmpty; // Auto-reset Event
|
||||
bool m_bNotEmpty;
|
||||
|
||||
MsgQueueLock m_MsgQueueLock;
|
||||
CNetworkMsgQueue m_MessageQueue;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef _GAMA_CLIENT_NET_NULL_HANDLER_H_
|
||||
#define _GAMA_CLIENT_NET_NULL_HANDLER_H_
|
||||
|
||||
#include "ClientEventHandler.h"
|
||||
|
||||
namespace ClientNet
|
||||
{
|
||||
class CNullClientEventHandler : public CClientEventHandler
|
||||
{
|
||||
public:
|
||||
|
||||
static CNullClientEventHandler& GetInstance()
|
||||
{
|
||||
static CNullClientEventHandler nullHandler;
|
||||
return nullHandler;
|
||||
}
|
||||
|
||||
virtual int OnDispatch(PktBase* lpPktBase, INET_Addr& peerAddr) { return 0; }
|
||||
virtual int OnOpen(int iErrorCode) { return 0; }
|
||||
virtual int OnClose() { return 0; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
#ifndef _GAMA_CLIENT_NULL_SESSION_H_
|
||||
#define _GAMA_CLIENT_NULL_SESSION_H_
|
||||
|
||||
#include "Session.h"
|
||||
#include "NullHandler.h"
|
||||
#include <cstdio>
|
||||
|
||||
namespace ClientNet
|
||||
{
|
||||
class NullSession : public CSession
|
||||
{
|
||||
public:
|
||||
|
||||
NullSession(CSessionMgr& SessionMgr)
|
||||
: CSession(SessionMgr, &NullHandler::GetInstance())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual ~NullSession() { m_lpEventHandler = NULL; }
|
||||
virtual CNetworkMsgBlock* GetNetworkMsgBlock(unsigned long dwSize, INET_Addr& addr, unsigned char cCmd)
|
||||
{
|
||||
fprintf(stderr, "SessionName:%s\tCmd:0x%02x\tReqSize:%6u\tNullSession cannot create message block!.\n",
|
||||
GetSessionName(), cCmd, dwSize);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
virtual int Open(INET_Addr& addr) { return 0; }
|
||||
virtual int Open(INET_Addr& addr, SOCKET hSocket) { return 0; } // Passive Socket
|
||||
virtual int Recv() { return 0; }
|
||||
virtual int Send(unsigned long dwMaxSendCount) { return 0; }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,124 @@
|
||||
#include "stdafx.h"
|
||||
#include "Session.h"
|
||||
#include "SessionMgr.h"
|
||||
#include "EventHandler.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include "GMMemory.h"
|
||||
|
||||
const int RECEIVE_BLOCK_SIZE = 65535;
|
||||
const int MAX_RECV_NUM_PER_PULSE = 20;
|
||||
const int MAX_SEND_NUM_PER_PULSE = 20;
|
||||
|
||||
namespace ClientNet
|
||||
{
|
||||
enum SessionFlags
|
||||
{
|
||||
SHUTDOWN_CALLED = (1 << 1),
|
||||
CLOSE_CALLED = (1 << 2)
|
||||
};
|
||||
}
|
||||
|
||||
ClientNet::CSession::CSession(DWORD dwSessionID, CEventHandler* lpEventHandler)
|
||||
: m_dwSessionID(dwSessionID),
|
||||
m_hSocket(INVALID_SOCKET),
|
||||
m_hEvent(WSACreateEvent()),
|
||||
m_lpEventHandler(lpEventHandler),
|
||||
m_Received(RECEIVE_BLOCK_SIZE),
|
||||
m_dwMaxRecvNumPerPulse(MAX_RECV_NUM_PER_PULSE),
|
||||
m_dwMaxSendNumPerPulse(MAX_SEND_NUM_PER_PULSE),
|
||||
m_dwFlags(0)
|
||||
{
|
||||
memset(m_szSessionName, 0, sizeof(char) * MAX_SESSION_NAME);
|
||||
}
|
||||
|
||||
|
||||
ClientNet::CSession::~CSession()
|
||||
{
|
||||
Close();
|
||||
|
||||
if(WSA_INVALID_EVENT != m_hEvent)
|
||||
{
|
||||
WSACloseEvent(m_hEvent);
|
||||
m_hEvent = WSA_INVALID_EVENT;
|
||||
}
|
||||
|
||||
delete m_lpEventHandler;
|
||||
m_lpEventHandler = 0;
|
||||
}
|
||||
|
||||
|
||||
bool ClientNet::CSession::IsValid()
|
||||
{
|
||||
if(NULL == m_lpEventHandler)
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CSession::IsValid - Handler is Invalid (NULL)\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(WSA_INVALID_EVENT == m_hEvent)
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CSession::IsValid - Event is Invalid (WSA_INVALID_EVENT)\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!m_Received.is_valid())
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CSession::IsValid - Receive MsgBlock is Invalid\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int ClientNet::CSession::Shutdown(int how)
|
||||
{
|
||||
if(INVALID_SOCKET != m_hSocket)
|
||||
{
|
||||
bool bFailed = false;
|
||||
|
||||
while(!bFailed && 0 != m_SendQueue.GetQueuedNum())
|
||||
{
|
||||
bFailed = (0 == Send(0xFFFFFFFF)) ? false : true;
|
||||
}
|
||||
|
||||
m_dwFlags |= SHUTDOWN_CALLED;
|
||||
|
||||
if(SOCKET_ERROR == shutdown(m_hSocket, how))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ClientNet::CSession::Close()
|
||||
{
|
||||
if(INVALID_SOCKET != m_hSocket)
|
||||
{
|
||||
Shutdown(SD_SEND);
|
||||
|
||||
if(SOCKET_ERROR == closesocket(m_hSocket))
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CSession::Close - closesocket error : %d\n", WSAGetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_hSocket = INVALID_SOCKET;
|
||||
m_dwFlags |= CLOSE_CALLED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ClientNet::CSession::IsShutdownCalled() const
|
||||
{
|
||||
return SHUTDOWN_CALLED == (m_dwFlags & SHUTDOWN_CALLED);
|
||||
}
|
||||
|
||||
bool ClientNet::CSession::IsCloseCalled() const
|
||||
{
|
||||
return CLOSE_CALLED == (m_dwFlags & CLOSE_CALLED);
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
#ifndef _GAMA_CLIENT_SESSION_H_
|
||||
#define _GAMA_CLIENT_SESSION_H_
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <Network/Address/INET_Addr.h>
|
||||
#include "NetworkMsgBlock.h"
|
||||
|
||||
namespace ClientNet
|
||||
{
|
||||
// forward decl;
|
||||
class CSessionMgr;
|
||||
class CEventHandler;
|
||||
|
||||
class CSession
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_SESSION_NAME = 16
|
||||
};
|
||||
|
||||
CSession(DWORD dwSessionID, CEventHandler* lpEventHandler);
|
||||
virtual ~CSession();
|
||||
|
||||
DWORD GetSessionID() const { return m_dwSessionID; }
|
||||
SOCKET GetSocket() const { return m_hSocket; }
|
||||
WSAEVENT GetEvent() const { return m_hEvent; }
|
||||
INET_Addr& GetPeerAddress() { return m_PeerAddress; }
|
||||
|
||||
CEventHandler* GetEventHandler() { return m_lpEventHandler; }
|
||||
void SetEventHandler(CEventHandler* lpEventHandler) { m_lpEventHandler = lpEventHandler; }
|
||||
|
||||
bool IsValid();
|
||||
|
||||
// Active Mode
|
||||
int Open(const char* addr, unsigned short port) { return Open(INET_Addr(addr, port)); }
|
||||
|
||||
virtual int Open(INET_Addr& addr) = 0; // Active Socket
|
||||
virtual int Open(INET_Addr& addr, SOCKET hSocket) = 0; // Passive Socket
|
||||
virtual int Recv() = 0;
|
||||
virtual int Send(unsigned long dwMaxSendCount) = 0;
|
||||
|
||||
int Send() { return Send(m_dwMaxSendNumPerPulse); }
|
||||
void SendPending(CNetworkMsgBlock* lpMsgBlock) { m_SendQueue.Enqueue(lpMsgBlock); Send(1); }
|
||||
|
||||
int Shutdown(int how);
|
||||
int Close();
|
||||
|
||||
bool IsShutdownCalled() const;
|
||||
bool IsCloseCalled() const;
|
||||
|
||||
const char* GetSessionName() { return m_szSessionName; }
|
||||
|
||||
protected:
|
||||
|
||||
DWORD m_dwSessionID;
|
||||
|
||||
SOCKET m_hSocket;
|
||||
WSAEVENT m_hEvent;
|
||||
CEventHandler* m_lpEventHandler;
|
||||
|
||||
unsigned long m_dwMaxRecvNumPerPulse;
|
||||
unsigned long m_dwMaxSendNumPerPulse;
|
||||
unsigned long m_dwFlags;
|
||||
|
||||
INET_Addr m_PeerAddress;
|
||||
|
||||
CNetworkMsgQueue m_SendQueue;
|
||||
CNetworkMsgBlock m_Received;
|
||||
|
||||
char m_szSessionName[MAX_SESSION_NAME];
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,405 @@
|
||||
#include "stdafx.h"
|
||||
#include "SessionMgr.h"
|
||||
#include "ClientEventHandler.h"
|
||||
#include "TCPSession.h"
|
||||
#include "UDPSession.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <ctime>
|
||||
|
||||
#include <mmsystem.h>
|
||||
#include "GMMemory.h"
|
||||
|
||||
const int MAX_DEFAULT_BLOCK_NUM = 100;
|
||||
const int DEFAULT_BLOCK_SIZE = 16384;
|
||||
|
||||
|
||||
namespace ClientNet
|
||||
{
|
||||
|
||||
CSessionMgr::CSessionMgr()
|
||||
: m_dwMaxSessionID(0), m_lpLockedMsgQueue(0)
|
||||
{
|
||||
memset(m_hHandleSet, 0, sizeof(HANDLE) * MAXIMUM_WAIT_OBJECTS);
|
||||
|
||||
WSADATA wsaData;
|
||||
WSAStartup(0x0202, &wsaData);
|
||||
|
||||
RearrangeHandleSet();
|
||||
}
|
||||
|
||||
CSessionMgr::~CSessionMgr()
|
||||
{
|
||||
SessionMap::iterator end = m_SessionMap.end();
|
||||
SessionMap::iterator pos = m_SessionMap.begin();
|
||||
|
||||
for(;pos != end; ++pos)
|
||||
{
|
||||
delete pos->second;
|
||||
}
|
||||
|
||||
m_SessionMap.clear();
|
||||
|
||||
WSACleanup();
|
||||
}
|
||||
|
||||
int CSessionMgr::Connect(INET_Addr& address, NetMsgType eNetMsgType, DWORD dwHandlerID)
|
||||
{
|
||||
if (MAXIMUM_WAIT_OBJECTS + 1 <= m_SessionMap.size())
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʹ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 == m_lpLockedMsgQueue)
|
||||
{
|
||||
// <20><EFBFBD><DEBD><EFBFBD> ť<><C5A5> <20><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD> <20>ʾҽ<CABE><D2BD>ϴ<EFBFBD>.
|
||||
return -1;
|
||||
}
|
||||
|
||||
DWORD dwSessionID = 0;
|
||||
|
||||
SessionMap::iterator pos;
|
||||
SessionMap::iterator end = m_SessionMap.end();
|
||||
|
||||
do
|
||||
{
|
||||
// <20><> <20><><EFBFBD><EFBFBD>ID<49><44> ã<>´<EFBFBD>.
|
||||
dwSessionID = ++m_dwMaxSessionID;
|
||||
pos = m_SessionMap.find(dwSessionID);
|
||||
}
|
||||
while(pos != end);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>, Ÿ<>Կ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> UDP<44><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20>ְ<EFBFBD> <20>Ѵ<EFBFBD>.
|
||||
CSession* lpSession = 0;
|
||||
#include "GMUndefNew.h"
|
||||
CEventHandler* lpEventHandler =
|
||||
new (std::nothrow) CThreadEventHandler(*m_lpLockedMsgQueue, dwHandlerID);
|
||||
#include "GMRedefNew.h"
|
||||
|
||||
if(0 == lpEventHandler)
|
||||
{
|
||||
// <20>̺<EFBFBD>Ʈ <20>ڵ鷯 <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(eNetMsgType)
|
||||
{
|
||||
case NET_MSG_REQ_TCP_OPEN:
|
||||
#include "GMUndefNew.h"
|
||||
lpSession = new (std::nothrow) CTCPSession(dwSessionID, lpEventHandler);
|
||||
#include "GMRedefNew.h"
|
||||
break;
|
||||
|
||||
case NET_MSG_REQ_UDP_OPEN:
|
||||
#include "GMUndefNew.h"
|
||||
lpSession = new (std::nothrow) CUDPSession(dwSessionID, lpEventHandler);
|
||||
#include "GMRedefNew.h"
|
||||
break;
|
||||
}
|
||||
|
||||
if(0 == lpSession || -1 == lpSession->Open(address))
|
||||
{
|
||||
delete lpSession;
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_SessionMap.insert(SessionMap::value_type(dwSessionID, lpSession));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CSessionMgr::RearrangeHandleSet()
|
||||
{
|
||||
SessionMap::iterator pos = m_SessionMap.begin();
|
||||
SessionMap::iterator end = m_SessionMap.end();
|
||||
|
||||
m_hHandleSet[0] = GetQueueHandle();
|
||||
|
||||
for (DWORD dwHandleIndex = 1; pos != end; ++pos, ++dwHandleIndex)
|
||||
{
|
||||
m_hHandleSet[dwHandleIndex] = pos->second->GetEvent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int CSessionMgr::HandleEvents(DWORD dwMilliseconds)
|
||||
{
|
||||
SessionMap::iterator pos = m_SessionMap.begin();
|
||||
SessionMap::iterator end = m_SessionMap.end();
|
||||
|
||||
CEventHandler* lpEventHandler = 0;
|
||||
|
||||
DWORD dwResult = WaitForMultipleObjects(
|
||||
m_SessionMap.size() + 1, m_hHandleSet, FALSE, dwMilliseconds);
|
||||
|
||||
if (WAIT_FAILED != dwResult)
|
||||
{
|
||||
// Ÿ<>Ӿƿ<D3BE> <20>ɷȴ<C9B7> <20>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD>и<EFBFBD> <20>ƴϸ<C6B4> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD>Ƽ<EFBFBD> üũ<C3BC><C5A9> <20><>.
|
||||
unsigned long dwRemoveCount = 0;
|
||||
|
||||
// ť <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||||
if (-1 == HandleMsgQueue())
|
||||
{
|
||||
++dwRemoveCount;
|
||||
}
|
||||
|
||||
// <20><>Ŷ ó<><C3B3><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||||
for (; pos != end;)
|
||||
{
|
||||
bool bRemove = false;
|
||||
CSession* lpSession = pos->second;
|
||||
|
||||
lpEventHandler = lpSession->GetEventHandler();
|
||||
if(0 == lpEventHandler)
|
||||
{
|
||||
fprintf(stderr, "CSessionMgr::HandleEvents - Session event handler is null\n");
|
||||
bRemove = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
int rc = WaitForSingleObject(lpSession->GetEvent(), 0);
|
||||
|
||||
if(WAIT_FAILED == rc)
|
||||
{
|
||||
fprintf(stderr, "CSessionMgr::HandleEvents - WaitForSingleObject failed : %d\n",
|
||||
WSAGetLastError());
|
||||
}
|
||||
else if(WAIT_TIMEOUT != rc && -1 == HandleIO(lpSession))
|
||||
{
|
||||
bRemove = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (-1 == lpEventHandler->OnDispatch(*lpSession))
|
||||
{
|
||||
bRemove = true;
|
||||
}
|
||||
|
||||
DWORD dwCurrentTime = timeGetTime();
|
||||
|
||||
if (lpEventHandler->IsTimeout(dwCurrentTime))
|
||||
{
|
||||
if(-1 == lpEventHandler->OnTimeout(*lpSession))
|
||||
{
|
||||
bRemove = true;
|
||||
}
|
||||
|
||||
lpEventHandler->UpdateTimeoutCalled(dwCurrentTime);
|
||||
}
|
||||
|
||||
if (bRemove)
|
||||
{
|
||||
lpEventHandler->OnDispatch(*lpSession);
|
||||
lpEventHandler->OnClose(*lpSession);
|
||||
|
||||
lpSession->Send();
|
||||
lpSession->Close();
|
||||
|
||||
delete lpSession;
|
||||
|
||||
pos = m_SessionMap.erase(pos);
|
||||
++dwRemoveCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < dwRemoveCount)
|
||||
{
|
||||
RearrangeHandleSet();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CSessionMgr::HandleIO(CSession* lpSession)
|
||||
{
|
||||
WSANETWORKEVENTS netEvents;
|
||||
memset(&netEvents, 0, sizeof(WSANETWORKEVENTS));
|
||||
|
||||
CEventHandler* lpEventHandler = lpSession->GetEventHandler();
|
||||
|
||||
// Enumerate the events
|
||||
int rc = WSAEnumNetworkEvents(lpSession->GetSocket(), lpSession->GetEvent(), &netEvents);
|
||||
|
||||
if (SOCKET_ERROR == rc)
|
||||
{
|
||||
fprintf(stderr, "CSessionMgr::HandleIO - WSAEnumNetworkEvents failed: %d\n", WSAGetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (netEvents.lNetworkEvents & FD_CONNECT)
|
||||
{
|
||||
fprintf(stderr, "CSessionMgr::HandleIO - Connect : %d\n", netEvents.iErrorCode[FD_CONNECT_BIT]);
|
||||
|
||||
lpEventHandler->OnOpen(*lpSession, netEvents.iErrorCode[FD_CONNECT_BIT]);
|
||||
}
|
||||
|
||||
if (netEvents.lNetworkEvents & FD_READ)
|
||||
{
|
||||
// Check for read error
|
||||
if (netEvents.iErrorCode[FD_READ_BIT] == 0)
|
||||
{
|
||||
if (-1 == lpSession->Recv())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "CSessionMgr::HandleIO - FD_READ error %d\n",
|
||||
netEvents.iErrorCode[FD_READ_BIT]);
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (netEvents.lNetworkEvents & FD_WRITE)
|
||||
{
|
||||
// Check for write error
|
||||
if (netEvents.iErrorCode[FD_WRITE_BIT] == 0)
|
||||
{
|
||||
if (-1 == lpSession->Send())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "CSessionMgr::HandleIO - FD_WRITE error %d\n",
|
||||
netEvents.iErrorCode[FD_WRITE_BIT]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (netEvents.lNetworkEvents & FD_CLOSE)
|
||||
{
|
||||
if (netEvents.iErrorCode[FD_CLOSE_BIT] == 0)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>д´<D0B4>.
|
||||
rc = lpSession->Recv();
|
||||
|
||||
if(-1 == rc)
|
||||
{
|
||||
lpSession->Close();
|
||||
return -1;
|
||||
}
|
||||
else if (rc != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
if(-1 == lpSession->Send())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "CSessionMgr::HandleIO - FD_CLOSE error %d\n",
|
||||
netEvents.iErrorCode[FD_CLOSE_BIT]);
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CSessionMgr::HandleMsgQueue()
|
||||
{
|
||||
CNetworkMsgQueue netMsgQueue;
|
||||
GetMessages(netMsgQueue, 0xFFFFFFFF);
|
||||
|
||||
CNetworkMsgBlock* lpMsgBlock = 0;
|
||||
DWORD dwHandleSetChange = 0;
|
||||
DWORD dwEventHandlerID = 0;
|
||||
|
||||
SessionMap::iterator pos;
|
||||
|
||||
while (0 != (lpMsgBlock = netMsgQueue.Dequeue()))
|
||||
{
|
||||
bool bDeleteMsg = true;
|
||||
|
||||
switch(lpMsgBlock->GetMsgType())
|
||||
{
|
||||
case NET_MSG_REQ_TCP_OPEN:
|
||||
case NET_MSG_REQ_UDP_OPEN:
|
||||
|
||||
dwEventHandlerID = lpMsgBlock->GetID();
|
||||
|
||||
if(0 == Connect(lpMsgBlock->GetAddress(),
|
||||
lpMsgBlock->GetMsgType(), dwEventHandlerID))
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20>ڵ<EFBFBD> set<65><74> <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD>. (<28>ݹ<EFBFBD><DDB9><EFBFBD> <20><><EFBFBD>߿<EFBFBD> OnOpenȣ<6E><C8A3><EFBFBD><EFBFBD> <20><EFBFBD><DFBB>Ѵ<EFBFBD>)
|
||||
++dwHandleSetChange;
|
||||
}
|
||||
else
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD> <20>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̴<EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Callback<63><6B><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
int nError = WSAGetLastError();
|
||||
if (0 == nError) { nError = INT_MAX; }
|
||||
|
||||
if(0 != m_lpLockedMsgQueue)
|
||||
{
|
||||
CNetworkMsgBlock* lpAckMsgBlock =
|
||||
CNetworkMsgPool::GetInstance().GetNetworkMsgBlock(sizeof(int), INET_Addr());
|
||||
|
||||
if(0 != lpAckMsgBlock)
|
||||
{
|
||||
lpAckMsgBlock->SetID(dwEventHandlerID);
|
||||
lpAckMsgBlock->SetMsgType(NET_MSG_ACK_OPEN);
|
||||
|
||||
lpAckMsgBlock->push(nError);
|
||||
m_lpLockedMsgQueue->PutMessage(lpAckMsgBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NET_MSG_REQ_CLOSE:
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ã<><C3A3> Shutdown/Close<73><65> ȣ<><C8A3><EFBFBD>Ѵ<EFBFBD>. (<28>ݹ<EFBFBD><DDB9><EFBFBD> <20><><EFBFBD>߿<EFBFBD> OnCloseȣ<65><C8A3><EFBFBD><EFBFBD> <20><EFBFBD><DFBB>Ѵ<EFBFBD>)
|
||||
pos = m_SessionMap.find(lpMsgBlock->GetID());
|
||||
if (pos != m_SessionMap.end())
|
||||
{
|
||||
pos->second->Close();
|
||||
}
|
||||
break;
|
||||
|
||||
case NET_MSG_REQ_SEND:
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ã<><C3A3> <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD> ť<><C5A5> <20>ִ´<D6B4>. (<28>ݹ<EFBFBD><DDB9><EFBFBD> <20><><EFBFBD><EFBFBD>.)
|
||||
pos = m_SessionMap.find(lpMsgBlock->GetID());
|
||||
if (pos != m_SessionMap.end())
|
||||
{
|
||||
pos->second->SendPending(lpMsgBlock);
|
||||
bDeleteMsg = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (bDeleteMsg)
|
||||
{
|
||||
lpMsgBlock->SetMsgType(NET_MSG_FREE);
|
||||
CNetworkMsgPool::GetInstance().FreeNetworkMsgBlock(lpMsgBlock);
|
||||
}
|
||||
}
|
||||
|
||||
return (0 < dwHandleSetChange) ? -1 : 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#ifndef _GAMA_CLIENT_SESSION_MGR_H_
|
||||
#define _GAMA_CLIENT_SESSION_MGR_H_
|
||||
|
||||
#include "NetworkMsgBlock.h"
|
||||
#include <map>
|
||||
|
||||
#pragma comment(lib, "ws2_32")
|
||||
|
||||
namespace ClientNet
|
||||
{
|
||||
class CSession;
|
||||
|
||||
class CSessionMgr : public CUnboundedWaitableMsgQueue
|
||||
{
|
||||
public:
|
||||
|
||||
CSessionMgr();
|
||||
~CSessionMgr();
|
||||
|
||||
void SetDispatchQueue(CLockedMsgQueue& LockedMsgQueue) { m_lpLockedMsgQueue = &LockedMsgQueue; }
|
||||
CLockedMsgQueue* GetDispatchQueue() { return m_lpLockedMsgQueue; }
|
||||
|
||||
int HandleEvents(DWORD dwMilliseconds = INFINITE);
|
||||
|
||||
private:
|
||||
|
||||
void RearrangeHandleSet();
|
||||
|
||||
// <20>ش<EFBFBD> <20><><EFBFBD>ǿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -1, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0<><30> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
int Connect(INET_Addr& address, NetMsgType eNetMsgType, DWORD dwHandlerID);
|
||||
int HandleIO(CSession* lpSession);
|
||||
|
||||
// <20><EFBFBD><DEBD><EFBFBD> ť<><C5A5> <20><>Ŷ<EFBFBD><C5B6> ó<><C3B3><EFBFBD>Ѵ<EFBFBD>. HandleSet<65><74> <20><>ȭ<EFBFBD><C8AD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -1<><31> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
int HandleMsgQueue();
|
||||
|
||||
typedef std::map<DWORD, CSession*> SessionMap;
|
||||
|
||||
DWORD m_dwMaxSessionID;
|
||||
DWORD m_dwLastTimeoutCall;
|
||||
CLockedMsgQueue* m_lpLockedMsgQueue;
|
||||
|
||||
SessionMap m_SessionMap;
|
||||
HANDLE m_hHandleSet[MAXIMUM_WAIT_OBJECTS];
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,200 @@
|
||||
#include "stdafx.h"
|
||||
#include "TCPSession.h"
|
||||
#include "SessionMgr.h"
|
||||
#include "EventHandler.h"
|
||||
#include <cstdio>
|
||||
#include "GMMemory.h"
|
||||
|
||||
ClientNet::CTCPSession::CTCPSession(DWORD dwSessionID, CEventHandler* lpEventHandler)
|
||||
: CSession(dwSessionID, lpEventHandler), m_bClosing(FALSE)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ClientNet::CTCPSession::~CTCPSession()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
int ClientNet::CTCPSession::Open(INET_Addr& addr)
|
||||
{
|
||||
if(!IsValid())
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CTCPSession::Open - Invalid Session, Can't open now.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(INVALID_SOCKET != m_hSocket)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
m_hSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, NULL, WSA_FLAG_OVERLAPPED);
|
||||
if(INVALID_SOCKET == m_hSocket)
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CTCPSession::Open - Socket create error : %d\n", WSAGetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
// EventSelect
|
||||
int rc = WSAEventSelect(m_hSocket, m_hEvent, FD_CONNECT | FD_READ | FD_WRITE | FD_CLOSE);
|
||||
if(SOCKET_ERROR == rc)
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CTCPSession::Open - EventSelect error : %d\n", WSAGetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
// connect
|
||||
rc = connect(m_hSocket, &addr.get_addr(), addr.get_size());
|
||||
if(SOCKET_ERROR == rc)
|
||||
{
|
||||
int nError = WSAGetLastError();
|
||||
if(WSAEWOULDBLOCK != nError)
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CTCPSession::Open - Connect error : %d\n", nError);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
m_PeerAddress = addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ClientNet::CTCPSession::Open(INET_Addr& addr, SOCKET hSocket)
|
||||
{
|
||||
if(!IsValid())
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CTCPSession::Open - Invalid Session, Can't open now.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(INVALID_SOCKET == hSocket)
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CTCPSession::Open - Invalid Socket, Can't open now.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Close();
|
||||
m_hSocket = hSocket;
|
||||
|
||||
// EventSelect
|
||||
int rc = WSAEventSelect(m_hSocket, m_hEvent, FD_READ | FD_WRITE | FD_CLOSE);
|
||||
if(SOCKET_ERROR == rc)
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CTCPSession::Open - EventSelect error : %d\n", WSAGetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_PeerAddress = addr;
|
||||
return m_lpEventHandler->OnOpen(*this, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ClientNet::CTCPSession::Recv()
|
||||
{
|
||||
WSABUF wsaBuf;
|
||||
|
||||
for(unsigned long dwReadCount = 0;
|
||||
dwReadCount < m_dwMaxRecvNumPerPulse || 0 == m_Received.remain();
|
||||
++dwReadCount)
|
||||
{
|
||||
wsaBuf.buf = m_Received.wr_ptr();
|
||||
wsaBuf.len = static_cast<unsigned long>(m_Received.remain());
|
||||
|
||||
DWORD dwReceived = 0;
|
||||
DWORD dwFlags = 0;
|
||||
|
||||
int rc = WSARecv(m_hSocket, &wsaBuf, 1, &dwReceived, &dwFlags, NULL, NULL);
|
||||
if(SOCKET_ERROR == rc)
|
||||
{
|
||||
if(WSAEWOULDBLOCK != WSAGetLastError())
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CTCPSession::Recv - WSARecv error : %d\n", WSAGetLastError());
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
m_Received.wr_ptr(dwReceived);
|
||||
|
||||
if(-1 == m_lpEventHandler->OnReceived(m_Received))
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CTCPSession::Recv - TCP Packet is Invalid\n");
|
||||
}
|
||||
|
||||
m_Received.pop_read_data();
|
||||
|
||||
if(0 == dwReceived)
|
||||
{
|
||||
m_bClosing = TRUE;
|
||||
if(0 == m_SendQueue.GetQueuedNum())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ClientNet::CTCPSession::Send(unsigned long dwMaxSendCount)
|
||||
{
|
||||
CNetworkMsgBlock* lpMsgBlock = m_SendQueue.Dequeue();
|
||||
|
||||
WSABUF wsaBuf;
|
||||
DWORD dwSendCompleted = 0;
|
||||
DWORD dwFlags = 0;
|
||||
|
||||
int rc = 0;
|
||||
|
||||
for(unsigned long dwSendCount = 0;
|
||||
NULL != lpMsgBlock && dwSendCount < dwMaxSendCount; ++dwSendCount)
|
||||
{
|
||||
wsaBuf.buf = lpMsgBlock->rd_ptr();
|
||||
wsaBuf.len = static_cast<unsigned long>(lpMsgBlock->length());
|
||||
|
||||
dwSendCompleted = 0;
|
||||
|
||||
rc = WSASend(m_hSocket, &wsaBuf, 1, &dwSendCompleted, dwFlags, NULL, NULL);
|
||||
if(SOCKET_ERROR == rc)
|
||||
{
|
||||
if(WSAEWOULDBLOCK != WSAGetLastError())
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CTCPSession::Send - WSASend error : %d\n", WSAGetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
// WSAEWOULDBLOCK is NOT error
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
lpMsgBlock->rd_ptr(dwSendCompleted);
|
||||
|
||||
if(0 == lpMsgBlock->length())
|
||||
{
|
||||
CNetworkMsgPool::GetInstance().FreeNetworkMsgBlock(lpMsgBlock);
|
||||
lpMsgBlock = m_SendQueue.Dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
if(NULL != lpMsgBlock)
|
||||
{
|
||||
m_SendQueue.Enqueue(lpMsgBlock, true);
|
||||
}
|
||||
|
||||
if(m_bClosing && 0 == m_SendQueue.GetQueuedNum())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (SOCKET_ERROR != rc) ? 0 : -1;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef _GAMA_CLIENT_TCP_SESSION_H_
|
||||
|
||||
#include "Session.h"
|
||||
|
||||
|
||||
namespace ClientNet
|
||||
{
|
||||
class CTCPSession : public CSession
|
||||
{
|
||||
public:
|
||||
|
||||
CTCPSession(DWORD dwSessionID, CEventHandler* lpEventHandler);
|
||||
|
||||
virtual ~CTCPSession();
|
||||
virtual int Open(INET_Addr& addr); // Active Socket
|
||||
virtual int Open(INET_Addr& addr, SOCKET hSocket); // Passive Socket
|
||||
|
||||
virtual int Recv();
|
||||
virtual int Send(unsigned long dwMaxSendCount);
|
||||
|
||||
protected:
|
||||
|
||||
BOOL m_bClosing;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,156 @@
|
||||
#include "stdafx.h"
|
||||
#include "UDPSession.h"
|
||||
#include "SessionMgr.h"
|
||||
#include "EventHandler.h"
|
||||
#include <cstdio>
|
||||
#include "GMMemory.h"
|
||||
|
||||
ClientNet::CUDPSession::CUDPSession(DWORD dwSessionID, CEventHandler* lpEventHandler)
|
||||
: CSession(dwSessionID, lpEventHandler)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
ClientNet::CUDPSession::~CUDPSession()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
int ClientNet::CUDPSession::Open(INET_Addr& addr)
|
||||
{
|
||||
if(INVALID_SOCKET != m_hSocket)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
m_hSocket = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, NULL, WSA_FLAG_OVERLAPPED);
|
||||
if(INVALID_SOCKET == m_hSocket)
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CUDPSession::Open - Socket create error : %d\n", WSAGetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
BOOL bReuseAddr = TRUE;
|
||||
int rc = setsockopt(m_hSocket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&bReuseAddr), sizeof(BOOL));
|
||||
if(SOCKET_ERROR == rc)
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CUDPSession::Open - setsockopt error : %d\n", WSAGetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = bind(m_hSocket, &addr.get_addr(), addr.get_size());
|
||||
if(SOCKET_ERROR == rc)
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CUDPSession::Open - bind error : %d\n", WSAGetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
// EventSelect
|
||||
rc = WSAEventSelect(m_hSocket, m_hEvent, FD_READ | FD_WRITE);
|
||||
if(SOCKET_ERROR == rc)
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CUDPSession::Open - EventSelect error : %d\n", WSAGetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ClientNet::CUDPSession::Recv()
|
||||
{
|
||||
WSABUF wsaBuf;
|
||||
|
||||
for(unsigned long dwReadCount = 0;
|
||||
dwReadCount < m_dwMaxRecvNumPerPulse || 0 == m_Received.remain();
|
||||
++dwReadCount)
|
||||
{
|
||||
wsaBuf.buf = m_Received.wr_ptr();
|
||||
wsaBuf.len = static_cast<unsigned long>(m_Received.remain());
|
||||
|
||||
DWORD dwReceived = 0;
|
||||
DWORD dwFlags = 0;
|
||||
|
||||
INET_Addr& addr = m_Received.GetAddress();
|
||||
int addr_size = INET_Addr::get_addr_buffer_size();
|
||||
int rc = WSARecvFrom(m_hSocket, &wsaBuf, 1, &dwReceived, &dwFlags,
|
||||
&addr.get_addr(), &addr_size, NULL, NULL);
|
||||
|
||||
if(SOCKET_ERROR == rc)
|
||||
{
|
||||
if(WSAEWOULDBLOCK != WSAGetLastError())
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CUDPSession::Recv - WSARecvFrom error : %d\n", WSAGetLastError());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr.set_size(addr_size);
|
||||
m_Received.wr_ptr(dwReceived);
|
||||
|
||||
if(-1 == m_lpEventHandler->OnReceived(m_Received) || 0 != m_Received.length())
|
||||
{
|
||||
fprintf(stderr, "ClientNet::CUDPSession::Recv - UDP packet is invalid\n");
|
||||
}
|
||||
|
||||
m_Received.pop_read_data();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ClientNet::CUDPSession::Send(unsigned long dwMaxSendCount)
|
||||
{
|
||||
CNetworkMsgBlock* lpMsgBlock = m_SendQueue.Dequeue();
|
||||
|
||||
WSABUF wsaBuf;
|
||||
DWORD dwSendCompleted = 0;
|
||||
DWORD dwFlags = 0;
|
||||
|
||||
int rc = 0;
|
||||
|
||||
for(unsigned long dwSendCount = 0;
|
||||
NULL != lpMsgBlock && dwSendCount < dwMaxSendCount; ++dwSendCount)
|
||||
{
|
||||
wsaBuf.buf = lpMsgBlock->rd_ptr();
|
||||
wsaBuf.len = static_cast<unsigned long>(lpMsgBlock->length());
|
||||
|
||||
dwSendCompleted = 0;
|
||||
INET_Addr& addr = lpMsgBlock->GetAddress();
|
||||
|
||||
rc = WSASendTo(m_hSocket, &wsaBuf, 1, &dwSendCompleted, dwFlags,
|
||||
&addr.get_addr(), addr.get_size(), NULL, NULL);
|
||||
|
||||
if(SOCKET_ERROR == rc)
|
||||
{
|
||||
rc = 0;
|
||||
|
||||
if(WSAEWOULDBLOCK == WSAGetLastError())
|
||||
{
|
||||
// WSAEWOULDBLOCK<43≯<EFBFBD> <20><><EFBFBD>߿<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
fprintf(stderr, "ClientNet::CUDPSession::Send - WSASendTo error : %d\n", WSAGetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
CNetworkMsgPool::GetInstance().FreeNetworkMsgBlock(lpMsgBlock);
|
||||
lpMsgBlock = m_SendQueue.Dequeue();
|
||||
}
|
||||
|
||||
if(NULL != lpMsgBlock)
|
||||
{
|
||||
m_SendQueue.Enqueue(lpMsgBlock, true);
|
||||
}
|
||||
|
||||
return (SOCKET_ERROR != rc) ? 0 : -1;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef _GAMA_CLIENT_UDP_SESSION_H_
|
||||
#define _GAMA_CLIENT_UDP_SESSION_H_
|
||||
|
||||
#include "Session.h"
|
||||
|
||||
|
||||
namespace ClientNet
|
||||
{
|
||||
class CSessionMgr;
|
||||
|
||||
class CUDPSession : public CSession
|
||||
{
|
||||
public:
|
||||
|
||||
CUDPSession(DWORD dwSessionID, CEventHandler* lpEventHandler);
|
||||
|
||||
virtual ~CUDPSession();
|
||||
|
||||
virtual int Open(INET_Addr& addr);
|
||||
virtual int Open(INET_Addr& addr, SOCKET hSocket) { return -1; }
|
||||
virtual int Recv();
|
||||
virtual int Send(unsigned long dwMaxSendCount);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user