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;
|
||||
}
|
||||
Reference in New Issue
Block a user