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:
729
Server/RylServerProject/BaseLibrary/Network/Session/Session.cpp
Normal file
729
Server/RylServerProject/BaseLibrary/Network/Session/Session.cpp
Normal file
@@ -0,0 +1,729 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "Session.h"
|
||||
#include "../IOCP/Overlapped.h"
|
||||
#include "../IOCP/CompletionHandler.h"
|
||||
#include "../Winsock/SocketFactory.h"
|
||||
#include "../Address/INET_Addr.h"
|
||||
|
||||
#include "../Dispatch/Dispatch.h"
|
||||
#include "../Dispatch/ServerRequest.h"
|
||||
#include "../../Stream/Buffer/Buffer.h"
|
||||
#include "../../Stream/Buffer/BufferFactory.h"
|
||||
|
||||
#include "../../Log/ServerLog.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// SP : SessionPointer
|
||||
// DP : DispatchPointer
|
||||
|
||||
namespace SessionState
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
CONNECTED, // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
DISCONNECTED, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD>.
|
||||
MAX_SESSION_STATE
|
||||
};
|
||||
};
|
||||
|
||||
namespace SessionFlag
|
||||
{
|
||||
// 8bit SessionFlag
|
||||
enum Type
|
||||
{
|
||||
CONNECT_CALLED = ( 1 << 0 ), // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
DISCONNECT_PROCESSED = ( 1 << 1 ), // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
SHUTDOWN_CALLED = ( 1 << 2 ), // Shutdown<77><6E> ȣ<><C8A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
SHUTDOWN_PROCESSED = ( 1 << 3 ), // Shutdown ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
|
||||
SUSPEND_RECV = ( 1 << 4 ) // <20>÷<EFBFBD><C3B7>װ<EFBFBD> <20><><EFBFBD>õǾ<C3B5> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Recv<63><76> <20><><EFBFBD><EFBFBD>
|
||||
};
|
||||
};
|
||||
|
||||
namespace SessionConst
|
||||
{
|
||||
enum Data
|
||||
{
|
||||
MAX_RECV_BUFFER = 32768
|
||||
};
|
||||
}
|
||||
|
||||
CSession::CSession(CSessionPolicy& SessionPolicy)
|
||||
: m_hSocket(INVALID_SOCKET),
|
||||
m_nRefCount(0),
|
||||
m_SessionPolicy(SessionPolicy),
|
||||
|
||||
m_dwRecvPending(0),
|
||||
m_dwSendPending(0),
|
||||
|
||||
m_cCurrentStatus(SessionState::CONNECTED),
|
||||
m_cFlags(0),
|
||||
m_usPadding(0x4343)
|
||||
{
|
||||
m_SessionPolicy.AddRef();
|
||||
|
||||
m_lpRecvBuffer = CREATE_BUFFER(SessionPolicy.GetBufferFactory(), SessionConst::MAX_RECV_BUFFER);
|
||||
m_lpDispatch = SessionPolicy.GetDispatchFactory().CreateDispatch(*this);
|
||||
}
|
||||
|
||||
|
||||
CSession::~CSession()
|
||||
{
|
||||
{
|
||||
SessionLock::Syncronize sync(m_SessionLock);
|
||||
|
||||
InternalCloseSocket();
|
||||
|
||||
SAFE_RELEASE_BUFFER(m_lpRecvBuffer);
|
||||
m_SessionPolicy.GetDispatchFactory().DeleteDispatch(m_lpDispatch);
|
||||
|
||||
m_usPadding = 0x4444;
|
||||
}
|
||||
|
||||
m_SessionPolicy.Release();
|
||||
}
|
||||
|
||||
|
||||
// false <20><><EFBFBD>Ͻ<EFBFBD> Accept Pending<6E><67> <20><>.
|
||||
bool CSession::Process()
|
||||
{
|
||||
if(!m_lpDispatch)
|
||||
{
|
||||
ERRLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/CloseSocket - Failed Dispatch Pointer",
|
||||
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), m_hSocket);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
SessionState::Type eState = SessionState::MAX_SESSION_STATE;
|
||||
unsigned char cFlags = 0;
|
||||
|
||||
bool bCloseSocket = false;
|
||||
bool bCallConnected = false;
|
||||
bool bCallDisconnected = false;
|
||||
|
||||
{
|
||||
SessionLock::Syncronize sync(m_SessionLock);
|
||||
|
||||
eState = static_cast<SessionState::Type>(m_cCurrentStatus);
|
||||
|
||||
switch(m_cCurrentStatus)
|
||||
{
|
||||
case SessionState::CONNECTED:
|
||||
|
||||
if(SessionFlag::CONNECT_CALLED != (m_cFlags & SessionFlag::CONNECT_CALLED))
|
||||
{
|
||||
bCallConnected = true;
|
||||
m_cFlags |= SessionFlag::CONNECT_CALLED;
|
||||
}
|
||||
|
||||
if (!(m_cFlags & SessionFlag::SUSPEND_RECV) && 0 == m_dwRecvPending)
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>´<DEB4>.
|
||||
InternalRecv();
|
||||
}
|
||||
break;
|
||||
|
||||
case SessionState::DISCONNECTED:
|
||||
|
||||
if(SessionFlag::DISCONNECT_PROCESSED != (m_cFlags & SessionFlag::DISCONNECT_PROCESSED))
|
||||
{
|
||||
bCallDisconnected = true;
|
||||
m_Statistics.m_DisconnectedTime = time(0);
|
||||
m_cFlags |= SessionFlag::DISCONNECT_PROCESSED;
|
||||
}
|
||||
else if(INVALID_SOCKET == m_hSocket &&
|
||||
0 == m_dwRecvPending &&
|
||||
0 == m_dwSendPending &&
|
||||
0 == m_nRefCount)
|
||||
{
|
||||
InternalCloseSocket();
|
||||
|
||||
DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/Eliminate Session",
|
||||
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), m_hSocket);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
cFlags = m_cFlags;
|
||||
|
||||
++m_nRefCount;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20><>.
|
||||
if(bCallConnected)
|
||||
{
|
||||
DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/Connection Open - Process connected",
|
||||
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), m_hSocket);
|
||||
|
||||
m_lpDispatch->Connected();
|
||||
|
||||
m_Statistics.m_ConnectedTime = time(0);
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><>Ŷ<EFBFBD><C5B6> Dispatch<63><68>.
|
||||
if(SessionState::CONNECTED == eState && !m_lpDispatch->Dispatch())
|
||||
{
|
||||
DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/CloseSocket - Failed Dispatch",
|
||||
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), m_hSocket);
|
||||
|
||||
bCloseSocket = true;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20>ݱ<EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20><>.
|
||||
if(bCallDisconnected)
|
||||
{
|
||||
DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ Connection Closed - Process disconnect",
|
||||
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), m_hSocket);
|
||||
|
||||
m_lpDispatch->Disconnected();
|
||||
}
|
||||
|
||||
{
|
||||
SessionLock::Syncronize sync(m_SessionLock);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||||
InternalSend();
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Shutdown<77><6E> ȣ<><C8A3><EFBFBD>߾<EFBFBD><DFBE><EFBFBD><EFBFBD><EFBFBD> Shutdown ó<><C3B3><EFBFBD><EFBFBD> <20><>.
|
||||
if((m_cFlags & SessionFlag::SHUTDOWN_CALLED) &&
|
||||
m_SendQueue.empty() && INVALID_SOCKET != m_hSocket)
|
||||
{
|
||||
if(shutdown(m_hSocket, SD_SEND))
|
||||
{
|
||||
m_cFlags |= SessionFlag::SHUTDOWN_PROCESSED;
|
||||
}
|
||||
}
|
||||
|
||||
--m_nRefCount;
|
||||
|
||||
if(bCloseSocket)
|
||||
{
|
||||
InternalCloseSocket();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CSession::Dispatch(unsigned long dwReceivedBytes)
|
||||
{
|
||||
// <20><>Ŷ ó<><C3B3><EFBFBD><EFBFBD> <20>ϰ<EFBFBD>, ó<><C3B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>δ<EFBFBD>.
|
||||
m_lpRecvBuffer->wr_ptr(dwReceivedBytes);
|
||||
unsigned long dwDispatchSize = static_cast<unsigned long>(m_lpRecvBuffer->length());
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD> 0(<28><><EFBFBD><EFBFBD> <20>Ϸ<EFBFBD>) <20>̰ų<CCB0>, <20><>Ŷ ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD> Socket<65><74> Close<73>Ѵ<EFBFBD>.
|
||||
bool bResult = (0 != dwReceivedBytes &&
|
||||
m_lpDispatch->ParsePacket(m_lpRecvBuffer->rd_ptr(), &dwDispatchSize));
|
||||
|
||||
m_lpRecvBuffer->rd_ptr(dwDispatchSize);
|
||||
m_lpRecvBuffer->pop_read_data();
|
||||
|
||||
SessionLock::Syncronize sync(m_SessionLock);
|
||||
|
||||
m_Statistics.m_dwTotalReceived += dwReceivedBytes;
|
||||
--m_dwRecvPending;
|
||||
|
||||
if (!bResult)
|
||||
{
|
||||
DETLOG7(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/shutdown - %s : dwReceivedBytes:%d, ErrorCode:%d",
|
||||
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), m_hSocket,
|
||||
(0 == dwReceivedBytes) ? "Disconnected" : "Failed To Dispatch Packet",
|
||||
dwReceivedBytes, WSAGetLastError());
|
||||
|
||||
InternalCloseSocket();
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
void CSession::InternalCloseSocket()
|
||||
{
|
||||
if(INVALID_SOCKET != m_hSocket)
|
||||
{
|
||||
const char* szRemoteAddr = m_RemoteAddr.get_addr_string();
|
||||
|
||||
if(SOCKET_ERROR == shutdown(m_hSocket, SD_SEND))
|
||||
{
|
||||
DETLOG5(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ Shutdown failed - ErrorCode:%d",
|
||||
this, m_lpDispatch, szRemoteAddr, m_hSocket, WSAGetLastError());
|
||||
}
|
||||
|
||||
if(SOCKET_ERROR == closesocket(m_hSocket))
|
||||
{
|
||||
DETLOG5(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ InternalCloseSocket failed - ErrorCode:%d",
|
||||
this, m_lpDispatch, szRemoteAddr, m_hSocket, WSAGetLastError());
|
||||
}
|
||||
|
||||
const int MAX_BUFFER = 1024;
|
||||
char szBuffer[MAX_BUFFER];
|
||||
|
||||
if(0 < InternalPrintStatistics(szBuffer, MAX_BUFFER))
|
||||
{
|
||||
DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/ InternalCloseSocket - Statistics : %s",
|
||||
this, m_lpDispatch, szRemoteAddr, szBuffer);
|
||||
}
|
||||
|
||||
m_cFlags |= SessionFlag::SHUTDOWN_PROCESSED;
|
||||
m_hSocket = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
m_cCurrentStatus = SessionState::DISCONNECTED;
|
||||
}
|
||||
|
||||
|
||||
bool CSession::Shutdown()
|
||||
{
|
||||
SessionLock::Syncronize sync(m_SessionLock);
|
||||
m_cFlags |= SessionFlag::SHUTDOWN_CALLED;
|
||||
return false;
|
||||
}
|
||||
|
||||
LONG CSession::AddRef()
|
||||
{
|
||||
SessionLock::Syncronize sync(m_SessionLock);
|
||||
return ++m_nRefCount;
|
||||
}
|
||||
|
||||
|
||||
LONG CSession::Release()
|
||||
{
|
||||
SessionLock::Syncronize sync(m_SessionLock);
|
||||
return --m_nRefCount;
|
||||
}
|
||||
|
||||
|
||||
void CSession::CloseSession()
|
||||
{
|
||||
SessionLock::Syncronize sync(m_SessionLock);
|
||||
|
||||
DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/ InternalCloseSocket - SessionClose Called : %d",
|
||||
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), WSAGetLastError());
|
||||
|
||||
InternalCloseSocket();
|
||||
}
|
||||
|
||||
|
||||
bool CSession::IsConnected()
|
||||
{
|
||||
SessionLock::Syncronize sync(m_SessionLock);
|
||||
return (SessionState::CONNECTED == m_cCurrentStatus && m_hSocket != INVALID_SOCKET);
|
||||
}
|
||||
|
||||
|
||||
bool CSession::CalledConnected()
|
||||
{
|
||||
SessionLock::Syncronize sync(m_SessionLock);
|
||||
return SessionFlag::CONNECT_CALLED == (m_cFlags & SessionFlag::CONNECT_CALLED);
|
||||
}
|
||||
|
||||
bool CSession::CalledDisconnected()
|
||||
{
|
||||
SessionLock::Syncronize sync(m_SessionLock);
|
||||
return SessionFlag::DISCONNECT_PROCESSED == (m_cFlags & SessionFlag::DISCONNECT_PROCESSED);
|
||||
}
|
||||
|
||||
void CSession::SendCompleted(BOOL bResult, unsigned long dwSendedBytes)
|
||||
{
|
||||
SessionLock::Syncronize sync(m_SessionLock);
|
||||
|
||||
--m_dwSendPending;
|
||||
m_Statistics.m_dwTotalSendCompleted += dwSendedBytes;
|
||||
|
||||
if(!bResult)
|
||||
{
|
||||
DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/ InternalCloseSocket - Send Completion Error : %d",
|
||||
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), WSAGetLastError());
|
||||
|
||||
InternalCloseSocket();
|
||||
}
|
||||
else
|
||||
{
|
||||
InternalSend();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CSession::SetAddress(INET_Addr& remoteAddr, INET_Addr& localAddr)
|
||||
{
|
||||
m_RemoteAddr = remoteAddr;
|
||||
m_LocalAddr = localAddr;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& CSession::PrintStatistics(std::ostream& strm)
|
||||
{
|
||||
SessionLock::Syncronize sync(m_SessionLock);
|
||||
|
||||
const int MAX_BUFFER = 1024;
|
||||
char szBuffer[MAX_BUFFER];
|
||||
|
||||
int nLen = InternalPrintStatistics(szBuffer, MAX_BUFFER);
|
||||
|
||||
if(0 < nLen)
|
||||
{
|
||||
strm << szBuffer;
|
||||
}
|
||||
|
||||
return strm;
|
||||
}
|
||||
|
||||
|
||||
int CSession::InternalPrintStatistics(char* szBuffer, int nBufferLen)
|
||||
{
|
||||
const char* szMode = 0;
|
||||
|
||||
switch(m_cCurrentStatus)
|
||||
{
|
||||
case SessionState::CONNECTED: szMode = "CONNECTED"; break;
|
||||
case SessionState::DISCONNECTED: szMode = "DISCONNECTED"; break;
|
||||
default: szMode = "Unknown Mode"; break;
|
||||
}
|
||||
|
||||
int nLen = _snprintf(szBuffer, nBufferLen - 1,
|
||||
"[m_hSocket:0x%08x][%15s][DiffTime(Sec):%8f]"
|
||||
"[m_dwTotalReceived:%5d][m_dwTotalSendPending:%5d][m_dwTotalSendCompleted:%5d]"
|
||||
"[m_dwSendPending:%d][m_dwRecvPending:%d][m_nRefCount:%2d][flags:0x%02x]",
|
||||
|
||||
m_hSocket, szMode, difftime(time(0), m_Statistics.m_ConnectedTime),
|
||||
m_Statistics.m_dwTotalReceived, m_Statistics.m_dwTotalSendPending,
|
||||
m_Statistics.m_dwTotalSendCompleted,
|
||||
m_dwSendPending, m_dwRecvPending,
|
||||
m_nRefCount, m_cFlags);
|
||||
|
||||
szBuffer[nBufferLen - 1] = 0;
|
||||
return nLen;
|
||||
}
|
||||
|
||||
|
||||
bool CSession::InternalRecv()
|
||||
{
|
||||
if (m_cFlags & SessionFlag::SUSPEND_RECV)
|
||||
{
|
||||
DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ Recv suspending now",
|
||||
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), m_hSocket);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (0 != m_dwRecvPending)
|
||||
{
|
||||
DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ Recv pending now",
|
||||
this, m_lpDispatch, m_RemoteAddr.get_addr_string(), m_hSocket);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned long dwReceived = 0;
|
||||
unsigned long dwFlags = 0;
|
||||
|
||||
WSABUF wsaBuf;
|
||||
|
||||
wsaBuf.buf = m_lpRecvBuffer->wr_ptr();
|
||||
wsaBuf.len = static_cast<u_long>(m_lpRecvBuffer->remain());
|
||||
|
||||
COverlapped* lpOverlapped = m_SessionPolicy.GetOverlappedFactory().CreateRecv(this, m_lpRecvBuffer);
|
||||
|
||||
const char* lpErrorFmtString = 0;
|
||||
|
||||
if(0 != lpOverlapped)
|
||||
{
|
||||
if(SOCKET_ERROR == WSARecv(m_hSocket, &wsaBuf, 1,
|
||||
&dwReceived, &dwFlags, lpOverlapped, 0))
|
||||
{
|
||||
if(WSA_IO_PENDING != WSAGetLastError())
|
||||
{
|
||||
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/InternalCloseSocket"
|
||||
" - WSARecv Error - ErrorCode:%d";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/InternalCloseSocket"
|
||||
" - WSARecv Error - Create RecvOverlapped Failed - ErrorCode:%d";
|
||||
}
|
||||
|
||||
if(0 != lpErrorFmtString)
|
||||
{
|
||||
DETLOG5(g_SessionLog, lpErrorFmtString, this, m_lpDispatch,
|
||||
m_RemoteAddr.get_addr_string(), m_hSocket, WSAGetLastError());
|
||||
|
||||
InternalCloseSocket();
|
||||
|
||||
m_SessionPolicy.GetOverlappedFactory().DeleteOverlapped(lpOverlapped);
|
||||
return false;
|
||||
}
|
||||
|
||||
++m_dwRecvPending;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CSession::InternalRecvFrom()
|
||||
{
|
||||
if(0 != m_dwRecvPending)
|
||||
{
|
||||
//DETLOG4(g_SessionLog, "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ RecvFrom pending now",
|
||||
// this, m_lpDispatch, m_RemoteAddr.get_addr_string(), m_hSocket);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(INVALID_SOCKET == m_hSocket)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned long dwReceived = 0;
|
||||
unsigned long dwFlags = 0;
|
||||
|
||||
WSABUF wsaBuf;
|
||||
|
||||
wsaBuf.buf = m_lpRecvBuffer->wr_ptr();
|
||||
wsaBuf.len = static_cast<u_long>(m_lpRecvBuffer->remain());
|
||||
|
||||
COverlapped* lpOverlapped =
|
||||
m_SessionPolicy.GetOverlappedFactory().CreateRecv(this, m_lpRecvBuffer);
|
||||
|
||||
const char* lpErrorFmtString = 0;
|
||||
|
||||
if(0 != lpOverlapped)
|
||||
{
|
||||
INET_Addr& addr = m_lpRecvBuffer->get_addr();
|
||||
|
||||
if(SOCKET_ERROR == WSARecvFrom(m_hSocket, &wsaBuf, 1, &dwReceived, &dwFlags,
|
||||
&addr.get_addr(), addr.get_size_ptr(), lpOverlapped, 0))
|
||||
{
|
||||
if(WSA_IO_PENDING != WSAGetLastError())
|
||||
{
|
||||
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ InternalCloseSocket"
|
||||
" - WSARecvFrom Error - ErrorCode:%d";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/InternalCloseSocket"
|
||||
" - WSARecvFrom Error - Create RecvOverlapped Failed - ErrorCode:%d";
|
||||
}
|
||||
|
||||
if(0 != lpErrorFmtString)
|
||||
{
|
||||
DETLOG5(g_SessionLog, lpErrorFmtString, this, m_lpDispatch,
|
||||
m_RemoteAddr.get_addr_string(), m_hSocket, WSAGetLastError());
|
||||
|
||||
InternalCloseSocket();
|
||||
|
||||
if(0 != lpOverlapped)
|
||||
{
|
||||
m_SessionPolicy.GetOverlappedFactory().DeleteOverlapped(lpOverlapped);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
++m_dwRecvPending;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
CSession::SendResult CSession::InternalSend(CBuffer* lpBuffer)
|
||||
{
|
||||
if(0 != m_dwSendPending)
|
||||
{
|
||||
return SEND_NEXT_TURN;
|
||||
}
|
||||
|
||||
if(INVALID_SOCKET == m_hSocket)
|
||||
{
|
||||
return SEND_FAILED;
|
||||
}
|
||||
|
||||
const char* lpErrorFmtString = 0;
|
||||
COverlapped* lpOverlapped = 0;
|
||||
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
lpOverlapped = m_SessionPolicy.GetOverlappedFactory().CreateSend(this, lpBuffer);
|
||||
|
||||
if(0 != lpOverlapped)
|
||||
{
|
||||
unsigned long dwSentBytes = 0;
|
||||
|
||||
WSABUF wsaBuf;
|
||||
|
||||
wsaBuf.buf = lpBuffer->rd_ptr();
|
||||
wsaBuf.len = static_cast<u_long>(lpBuffer->length());
|
||||
|
||||
m_Statistics.m_dwTotalSendPending += wsaBuf.len;
|
||||
|
||||
if(SOCKET_ERROR == WSASend(m_hSocket, &wsaBuf, 1,
|
||||
&dwSentBytes, 0, lpOverlapped, 0))
|
||||
{
|
||||
if(WSA_IO_PENDING != WSAGetLastError())
|
||||
{
|
||||
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ "
|
||||
"InternalCloseSocket - WSASend Error - ErrorCode:%d";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ InternalCloseSocket"
|
||||
" - WSASend Error - Cannot Create SendOverlapped - ErrorCode:%d";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ InternalCloseSocket"
|
||||
" - WSASend Error - lpBuffer is 0 - ErrorCode:%d";
|
||||
}
|
||||
|
||||
if(0 != lpErrorFmtString)
|
||||
{
|
||||
DETLOG5(g_SessionLog, lpErrorFmtString, this, m_lpDispatch,
|
||||
m_RemoteAddr.get_addr_string(), m_hSocket, WSAGetLastError());
|
||||
|
||||
InternalCloseSocket();
|
||||
|
||||
if(0 != lpOverlapped)
|
||||
{
|
||||
lpOverlapped->SetBuffer(0);
|
||||
m_SessionPolicy.GetOverlappedFactory().DeleteOverlapped(lpOverlapped);
|
||||
}
|
||||
|
||||
return SEND_FAILED;
|
||||
}
|
||||
|
||||
++m_dwSendPending;
|
||||
return SEND_SUCCEEDED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CSession::SendResult CSession::InternalSendTo(CBuffer* lpBuffer)
|
||||
{
|
||||
if(0 != m_dwSendPending)
|
||||
{
|
||||
return SEND_NEXT_TURN;
|
||||
}
|
||||
|
||||
if(INVALID_SOCKET == m_hSocket)
|
||||
{
|
||||
return SEND_FAILED;
|
||||
}
|
||||
|
||||
const char* lpErrorFmtString = 0;
|
||||
COverlapped* lpOverlapped = 0;
|
||||
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
lpOverlapped = m_SessionPolicy.GetOverlappedFactory().CreateSend(this, lpBuffer);
|
||||
|
||||
if(0 != lpOverlapped)
|
||||
{
|
||||
unsigned long dwSentBytes = 0;
|
||||
|
||||
WSABUF wsaBuf;
|
||||
|
||||
wsaBuf.buf = lpBuffer->rd_ptr();
|
||||
wsaBuf.len = static_cast<u_long>(lpBuffer->length());
|
||||
|
||||
m_Statistics.m_dwTotalSendPending += wsaBuf.len;
|
||||
|
||||
INET_Addr& addr = lpBuffer->get_addr();
|
||||
|
||||
if(SOCKET_ERROR == WSASendTo(m_hSocket, &wsaBuf, 1,
|
||||
&dwSentBytes, 0, &addr.get_addr(), addr.get_size(), lpOverlapped, 0))
|
||||
{
|
||||
if(WSA_IO_PENDING != WSAGetLastError())
|
||||
{
|
||||
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ "
|
||||
"InternalCloseSocket - WSASendTo Error - ErrorCode:%d";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ InternalCloseSocket"
|
||||
" - WSASendTo Error - Cannot Create SendOverlapped - ErrorCode:%d";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lpErrorFmtString = "SP:0x%p/DP:0x%p/IP:%15s/SOCKET:0x%p/ InternalCloseSocket"
|
||||
" - WSASendTo Error - lpBuffer is 0 - ErrorCode:%d";
|
||||
}
|
||||
|
||||
if(0 != lpErrorFmtString)
|
||||
{
|
||||
DETLOG5(g_SessionLog, lpErrorFmtString, this, m_lpDispatch,
|
||||
m_RemoteAddr.get_addr_string(), m_hSocket, WSAGetLastError());
|
||||
|
||||
InternalCloseSocket();
|
||||
|
||||
if(0 != lpOverlapped)
|
||||
{
|
||||
lpOverlapped->SetBuffer(0);
|
||||
m_SessionPolicy.GetOverlappedFactory().DeleteOverlapped(lpOverlapped);
|
||||
}
|
||||
|
||||
return SEND_FAILED;
|
||||
}
|
||||
|
||||
++m_dwSendPending;
|
||||
return SEND_SUCCEEDED;
|
||||
}
|
||||
|
||||
bool CSession::SendPending(CBuffer* lpBuffer)
|
||||
{
|
||||
SessionLock::Syncronize sync(m_SessionLock);
|
||||
|
||||
if(!(SessionFlag::SHUTDOWN_CALLED & m_cFlags) && INVALID_SOCKET != m_hSocket)
|
||||
{
|
||||
m_SendQueue.enqueue(lpBuffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSession::InternalSend()
|
||||
{
|
||||
SendResult eSendResult = SEND_SUCCEEDED;
|
||||
|
||||
if(0 == m_dwSendPending)
|
||||
{
|
||||
CBuffer* lpBuffer = m_SendQueue.dequeue();
|
||||
|
||||
if(0 != lpBuffer)
|
||||
{
|
||||
eSendResult = (0 == lpBuffer->get_addr().get_size()) ?
|
||||
InternalSend(lpBuffer) : InternalSendTo(lpBuffer);
|
||||
|
||||
if(SEND_SUCCEEDED != eSendResult)
|
||||
{
|
||||
m_SendQueue.enqueue(lpBuffer, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (SEND_FAILED != eSendResult);
|
||||
}
|
||||
|
||||
void CSession::SuspendRecv()
|
||||
{
|
||||
SessionLock::Syncronize sync(m_SessionLock);
|
||||
m_cFlags |= SessionFlag::SUSPEND_RECV;
|
||||
}
|
||||
|
||||
void CSession::ResumeRecv()
|
||||
{
|
||||
SessionLock::Syncronize sync(m_SessionLock);
|
||||
m_cFlags &= ~SessionFlag::SUSPEND_RECV;
|
||||
}
|
||||
159
Server/RylServerProject/BaseLibrary/Network/Session/Session.h
Normal file
159
Server/RylServerProject/BaseLibrary/Network/Session/Session.h
Normal file
@@ -0,0 +1,159 @@
|
||||
#ifndef _CSESSION_H_
|
||||
#define _CSESSION_H_
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <mswsock.h>
|
||||
#include <iosfwd>
|
||||
|
||||
#include "SessionPolicy.h"
|
||||
|
||||
#include "../Address/INET_Addr.h"
|
||||
#include "../IOCP/Overlapped.h"
|
||||
#include "../../Thread/Lock.h"
|
||||
#include "../../Stream/Buffer/BufferQueue.h"
|
||||
|
||||
#pragma comment(lib, "ws2_32")
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
class CBuffer;
|
||||
class CBufferFactory;
|
||||
|
||||
class CPacketDispatch;
|
||||
class CDispatchFactory;
|
||||
|
||||
class CCompletionHandler;
|
||||
class CSocketBaseFactory;
|
||||
|
||||
|
||||
struct SessionStatistics
|
||||
{
|
||||
unsigned long m_dwTotalReceived; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>.
|
||||
unsigned long m_dwTotalSendPending; // <20><><EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD> pending<6E><67> <20><>.
|
||||
unsigned long m_dwTotalSendCompleted; // Send<6E>Ϸ<EFBFBD><CFB7><EFBFBD> <20><>.
|
||||
time_t m_ConnectedTime; // Connect<63><74> <20>ð<EFBFBD>.
|
||||
time_t m_DisconnectedTime; // Disconnected<65><64> <20>ð<EFBFBD>.
|
||||
|
||||
SessionStatistics::SessionStatistics()
|
||||
: m_dwTotalReceived(0), m_dwTotalSendPending(0), m_dwTotalSendCompleted(0),
|
||||
m_ConnectedTime(0), m_DisconnectedTime(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
m_dwTotalReceived = m_dwTotalSendPending = m_dwTotalSendCompleted = 0;
|
||||
m_ConnectedTime = m_DisconnectedTime = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class CSession
|
||||
{
|
||||
public:
|
||||
|
||||
CSession(CSessionPolicy& SessionPolicy);
|
||||
~CSession();
|
||||
|
||||
enum SendResult
|
||||
{
|
||||
SEND_SUCCEEDED,
|
||||
SEND_FAILED,
|
||||
SEND_NEXT_TURN,
|
||||
};
|
||||
|
||||
LONG AddRef();
|
||||
LONG Release();
|
||||
|
||||
bool IsConnected();
|
||||
void CloseSession();
|
||||
|
||||
bool CalledConnected();
|
||||
bool CalledDisconnected();
|
||||
|
||||
void SetAddress(INET_Addr& remoteAddr, INET_Addr& localAddr);
|
||||
INET_Addr& GetRemoteAddr() { return m_RemoteAddr; }
|
||||
INET_Addr& GetLocalAddr() { return m_LocalAddr; }
|
||||
|
||||
CPacketDispatch* GetDispatch() { return m_lpDispatch; }
|
||||
CSessionPolicy& GetPolicy() { return m_SessionPolicy; }
|
||||
|
||||
const SessionStatistics& GetStatistics() { return m_Statistics; }
|
||||
|
||||
bool SendPending(CBuffer* lpBuffer);
|
||||
void SendCompleted(BOOL bResult, unsigned long dwSendedBytes);
|
||||
|
||||
bool Process();
|
||||
bool Dispatch(unsigned long dwReceivedBytes);
|
||||
|
||||
bool Recv() { SessionLock::Syncronize sync(m_SessionLock); return InternalRecv(); }
|
||||
bool RecvFrom() { SessionLock::Syncronize sync(m_SessionLock); return InternalRecvFrom(); }
|
||||
bool Send() { SessionLock::Syncronize sync(m_SessionLock); return InternalSend(); }
|
||||
|
||||
bool Connect(CCompletionHandler& Handler, LPSTR lpConnectAddress, unsigned short usPort);
|
||||
bool Shutdown();
|
||||
|
||||
void SuspendRecv();
|
||||
void ResumeRecv();
|
||||
|
||||
friend std::ostream& Log(std::ostream& strm, CSession* lpSession) { return (0 != lpSession) ? lpSession->PrintStatistics(strm) : strm; }
|
||||
friend std::ostream& Log(std::ostream& strm, CSession& Session) { return Session.PrintStatistics(strm); }
|
||||
|
||||
private:
|
||||
|
||||
bool isValid() const { return (0 != m_lpRecvBuffer && 0 != m_lpDispatch); }
|
||||
void Socket(SOCKET hSocket) { m_hSocket = hSocket; }
|
||||
SOCKET Socket() { return m_hSocket; }
|
||||
|
||||
bool InternalRecv();
|
||||
bool InternalRecvFrom();
|
||||
|
||||
bool InternalSend();
|
||||
SendResult InternalSend(CBuffer* lpBuffer);
|
||||
SendResult InternalSendTo(CBuffer* lpBuffer);
|
||||
|
||||
void InternalCloseSocket();
|
||||
|
||||
// Desc : <20>α<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
std::ostream& PrintStatistics(std::ostream& strm);
|
||||
int InternalPrintStatistics(char* szBuffer, int nBufferLen);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
|
||||
typedef CCSLock SessionLock; // Critical Section Lock (24byte)
|
||||
|
||||
SessionLock m_SessionLock; // Multithreadȯ<64><C8AF><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Lock
|
||||
CACHE_PAD(LockPadding, sizeof(SessionLock));// Cache-align<67><6E> <20><><EFBFBD><EFBFBD> Padding
|
||||
|
||||
// Shared class
|
||||
CSessionPolicy& m_SessionPolicy; // Session Policy
|
||||
|
||||
// Per-session data
|
||||
CPacketDispatch* m_lpDispatch; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> PacketDispatchŬ<68><C5AC><EFBFBD><EFBFBD>
|
||||
|
||||
SOCKET m_hSocket; // Socket Descriptor
|
||||
|
||||
INET_Addr m_RemoteAddr; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ּ<EFBFBD>
|
||||
INET_Addr m_LocalAddr; // <20><><EFBFBD><EFBFBD> <20>ּ<EFBFBD>
|
||||
|
||||
CBuffer* m_lpRecvBuffer; // Recv Buffer
|
||||
CBufferQueue m_SendQueue; // SendQueue
|
||||
|
||||
unsigned long m_dwRecvPending; // Recv PendingCount
|
||||
unsigned long m_dwSendPending; // Send PendingCount
|
||||
|
||||
LONG m_nRefCount; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>۷<EFBFBD><DBB7><EFBFBD> ī<><C4AB>Ʈ
|
||||
|
||||
SessionStatistics m_Statistics; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
|
||||
unsigned char m_cCurrentStatus; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
unsigned char m_cFlags; // <20><><EFBFBD><EFBFBD> flag
|
||||
unsigned short m_usPadding; // <20>е<EFBFBD><D0B5><EFBFBD>
|
||||
|
||||
friend class CListener;
|
||||
friend class CIOCPNet;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,114 @@
|
||||
#include "SessionMgr.h"
|
||||
#include "Session.h"
|
||||
|
||||
#include <boost/pool/object_pool.hpp>
|
||||
|
||||
CSessionMgr::CSessionMgr()
|
||||
: m_lpSessionPool(new boost::pool<>(sizeof(CSession)))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
CSessionMgr::~CSessionMgr()
|
||||
{
|
||||
// <20><>Ÿ <20><><EFBFBD><EFBFBD><EFBFBD>۾<EFBFBD>.
|
||||
Destroy(5000);
|
||||
|
||||
delete m_lpSessionPool;
|
||||
}
|
||||
|
||||
void CSessionMgr::Add(CSession* lpSession)
|
||||
{
|
||||
if(0 != lpSession)
|
||||
{
|
||||
SessionLock::Syncronize sync(m_AddLock);
|
||||
m_to_be_added.push_back(lpSession);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CSessionMgr::InternalProcess()
|
||||
{
|
||||
{
|
||||
SessionLock::Syncronize sync(m_AddLock);
|
||||
m_current.splice(m_current.end(), m_to_be_added);
|
||||
}
|
||||
|
||||
SessionSet::iterator pos = m_current.begin();
|
||||
SessionSet::iterator end = m_current.end();
|
||||
|
||||
CSession* lpSession = 0;
|
||||
|
||||
for(;pos != end;)
|
||||
{
|
||||
lpSession = *pos;
|
||||
|
||||
if(!lpSession->Process())
|
||||
{
|
||||
pos = m_current.erase(pos);
|
||||
DeleteSession(lpSession);
|
||||
}
|
||||
else
|
||||
{
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CSessionMgr::Destroy(unsigned long dwWaitTime)
|
||||
{
|
||||
SessionLock::Syncronize process_sync(m_ProcessLock);
|
||||
|
||||
{
|
||||
SessionLock::Syncronize sync(m_AddLock);
|
||||
m_current.splice(m_current.end(), m_to_be_added);
|
||||
}
|
||||
|
||||
SessionSet::iterator pos = m_current.begin();
|
||||
SessionSet::iterator end = m_current.end();
|
||||
|
||||
CSession* lpSession = 0;
|
||||
|
||||
for(;pos != end; ++pos)
|
||||
{
|
||||
lpSession = *pos;
|
||||
lpSession->CloseSession();
|
||||
}
|
||||
|
||||
pos = m_current.begin();
|
||||
end = m_current.end();
|
||||
|
||||
unsigned long dwTime = timeGetTime();
|
||||
|
||||
while(!m_current.empty()
|
||||
&& timeGetTime() < dwTime + dwWaitTime)
|
||||
{
|
||||
InternalProcess();
|
||||
Sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CSession* CSessionMgr::CreateSession(CSessionPolicy& SessionPolicy)
|
||||
{
|
||||
SessionLock::Syncronize sync(m_CreationLock);
|
||||
|
||||
void* ptr = m_lpSessionPool->malloc();
|
||||
|
||||
return ptr ? new (ptr) CSession(SessionPolicy) : 0;
|
||||
}
|
||||
|
||||
|
||||
void CSessionMgr::DeleteSession(CSession* lpSession)
|
||||
{
|
||||
SessionLock::Syncronize sync(m_CreationLock);
|
||||
|
||||
if(0 != m_lpSessionPool && 0 != lpSession)
|
||||
{
|
||||
lpSession->~CSession();
|
||||
m_lpSessionPool->free(lpSession);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
#ifndef _NETWORK_SESSION_MGR_H_
|
||||
#define _NETWORK_SESSION_MGR_H_
|
||||
|
||||
#include "../../Thread/Lock.h"
|
||||
|
||||
#include <list>
|
||||
#include <boost/pool/poolfwd.hpp>
|
||||
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
class CSession;
|
||||
class CSessionPolicy;
|
||||
|
||||
class CSessionMgr
|
||||
{
|
||||
public:
|
||||
|
||||
CSessionMgr();
|
||||
~CSessionMgr();
|
||||
|
||||
void Add(CSession* lpSession);
|
||||
void Process() { SessionLock::Syncronize process_sync(m_ProcessLock); InternalProcess(); }
|
||||
void Destroy(unsigned long dwWaitTime = INFINITE);
|
||||
|
||||
size_t GetSessionNum() { SessionLock::Syncronize process_sync(m_ProcessLock); return m_current.size(); }
|
||||
|
||||
CSession* CreateSession(CSessionPolicy& SessionPolicy);
|
||||
void DeleteSession(CSession* lpSession);
|
||||
|
||||
private:
|
||||
|
||||
void InternalProcess();
|
||||
|
||||
typedef CCSLock SessionLock;
|
||||
typedef std::list<CSession*> SessionSet;
|
||||
|
||||
SessionLock m_AddLock;
|
||||
SessionSet m_to_be_added;
|
||||
|
||||
CACHE_PAD(AddLockPad, sizeof(SessionSet));
|
||||
|
||||
SessionLock m_ProcessLock;
|
||||
SessionSet m_current;
|
||||
|
||||
CACHE_PAD(ProcessLockPad, sizeof(SessionSet));
|
||||
|
||||
SessionLock m_CreationLock;
|
||||
boost::pool<>* m_lpSessionPool;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "stdafx.h"
|
||||
#include "SessionPolicy.h"
|
||||
|
||||
#include "../IOCP/Overlapped.h"
|
||||
#include "../Dispatch/Dispatch.h"
|
||||
#include "../Winsock/SocketFactory.h"
|
||||
#include "../../Stream/Buffer/BufferFactory.h"
|
||||
|
||||
CSessionPolicy::CSessionPolicy(CSocketFactory* lpSocketFactory,
|
||||
CBufferFactory* lpBufferFactory,
|
||||
CDispatchFactory* lpDispatchFactory,
|
||||
COverlappedFactory* lpOverlappedFactory)
|
||||
: m_lpSocketFactory(lpSocketFactory),
|
||||
m_lpBufferFactory(lpBufferFactory),
|
||||
m_lpDispatchFactory(lpDispatchFactory),
|
||||
m_lpOverlappedFactory(lpOverlappedFactory),
|
||||
m_nRefCount(1)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CSessionPolicy::~CSessionPolicy()
|
||||
{
|
||||
delete m_lpSocketFactory;
|
||||
delete m_lpBufferFactory;
|
||||
delete m_lpDispatchFactory;
|
||||
delete m_lpOverlappedFactory;
|
||||
}
|
||||
|
||||
|
||||
LONG CSessionPolicy::AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&m_nRefCount);
|
||||
}
|
||||
|
||||
LONG CSessionPolicy::Release()
|
||||
{
|
||||
LONG nRefCount = InterlockedDecrement(&m_nRefCount);
|
||||
if(0 == nRefCount)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
return nRefCount;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#ifndef _GAMA_NETWORK_LIBRARY_SESSION_POLICY_H_
|
||||
#define _GAMA_NETWORK_LIBRARY_SESSION_POLICY_H_
|
||||
|
||||
// forward decl.
|
||||
class CSocketFactory;
|
||||
class CBufferFactory;
|
||||
class CDispatchFactory;
|
||||
class COverlappedFactory;
|
||||
|
||||
class CSessionPolicy
|
||||
{
|
||||
public:
|
||||
|
||||
LONG AddRef();
|
||||
LONG Release();
|
||||
|
||||
bool IsValid()
|
||||
{
|
||||
return 0 != m_lpBufferFactory && 0 != m_lpSocketFactory &&
|
||||
0 != m_lpDispatchFactory && 0 != m_lpOverlappedFactory;
|
||||
}
|
||||
|
||||
CSocketFactory& GetSocketFactory() { return *m_lpSocketFactory; }
|
||||
CBufferFactory& GetBufferFactory() { return *m_lpBufferFactory; }
|
||||
CDispatchFactory& GetDispatchFactory() { return *m_lpDispatchFactory; }
|
||||
COverlappedFactory& GetOverlappedFactory() { return *m_lpOverlappedFactory; }
|
||||
|
||||
// Creation Factory
|
||||
template <class SocketFactory, class BufferFactory, class DispatchFactory, class OverlappedFactory>
|
||||
static CSessionPolicy* Create()
|
||||
{
|
||||
CSessionPolicy* lpSessionPolicy = new (std::nothrow) CSessionPolicy(
|
||||
new SocketFactory,
|
||||
new BufferFactory,
|
||||
new DispatchFactory,
|
||||
new OverlappedFactory);
|
||||
|
||||
if(0 == lpSessionPolicy || !lpSessionPolicy->IsValid())
|
||||
{
|
||||
delete lpSessionPolicy;
|
||||
lpSessionPolicy = 0;
|
||||
}
|
||||
|
||||
return lpSessionPolicy;
|
||||
}
|
||||
|
||||
// edith 2009.08.14 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><DEB8><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Private Ÿ<>Կ<EFBFBD><D4BF><EFBFBD> Public Ÿ<><C5B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
~CSessionPolicy();
|
||||
|
||||
private:
|
||||
|
||||
CSessionPolicy(
|
||||
CSocketFactory* lpSocketFactory,
|
||||
CBufferFactory* lpBufferFactory,
|
||||
CDispatchFactory* lpDispatchFactory,
|
||||
COverlappedFactory* lpOverlappedFactory);
|
||||
|
||||
|
||||
CSocketFactory* m_lpSocketFactory;
|
||||
CBufferFactory* m_lpBufferFactory;
|
||||
CDispatchFactory* m_lpDispatchFactory;
|
||||
COverlappedFactory* m_lpOverlappedFactory;
|
||||
LONG m_nRefCount;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user