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:
2025-11-29 20:17:20 +09:00
parent 5d3cd64a25
commit dd97ddec92
11602 changed files with 1446576 additions and 0 deletions

View 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;
}

View 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

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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