// NetServer.cpp: implementation of the CNetServer class.
|
//
|
//////////////////////////////////////////////////////////////////////
|
|
#include "stdafx.h"
|
#include "NetServer.h"
|
|
#ifdef _DEBUG
|
#undef THIS_FILE
|
static char THIS_FILE[]=__FILE__;
|
#define new DEBUG_NEW
|
#endif
|
|
//////////////////////////////////////////////////////////////////////
|
// Construction/Destruction
|
//////////////////////////////////////////////////////////////////////
|
|
CNetServer::CNetServer()
|
{
|
StartUp();
|
|
m_pN2M = NULL;
|
m_pPacket = NULL;
|
m_nTotalPacketCount = 0;
|
m_nPacketIdx = 0;
|
|
m_pClientJoiner = NULL;
|
m_nClientCount = 0;
|
|
m_bAcceptSameIP = FALSE;
|
|
InitializeCriticalSection(&m_csPacket);
|
}
|
|
CNetServer::~CNetServer()
|
{
|
DeinitNetwork();
|
|
CleanUp();
|
|
if (m_pPacket)
|
{
|
delete [] m_pPacket;
|
m_pPacket = NULL;
|
}
|
if (m_pClientJoiner)
|
{
|
delete [] m_pClientJoiner;
|
m_pClientJoiner = NULL;
|
m_nClientCount = 0;
|
}
|
DeleteCriticalSection(&m_csPacket);
|
|
//TRACE("------- CNetServer -------- close \n");
|
}
|
|
BOOL CNetServer::SetClientInfo(int ST, int nCount, short sNetworkCode, short sVersion, BOOL bUseHeartbeat, int nPacketCount)
|
{
|
if (nCount <= 0)
|
return FALSE;
|
|
int i;
|
|
m_Clientint = ST; // ¿¬°áÇÒ ClientÀÇ Á¾·ù.
|
if (nPacketCount <= 0)
|
nPacketCount = 200;
|
|
m_nClientCount = nCount;
|
m_nTotalPacketCount = nCount * nPacketCount;
|
m_pPacket = new CNetPacket[m_nTotalPacketCount];
|
for (i = 0; i < m_nTotalPacketCount; i++)
|
m_pPacket[i].SetVersion(sNetworkCode, sVersion);
|
|
m_pClientJoiner = new CNetJoiner[nCount];
|
for (i = 0; i < nCount; i++)
|
m_pClientJoiner[i].SetUseHeartbeat(bUseHeartbeat);
|
|
m_sNetworkCode = sNetworkCode;
|
m_sVersion = sVersion;
|
|
return TRUE;
|
}
|
|
BOOL CNetServer::InitNetwork(NetworkMode Mode, int nSocketCount, int nPort, CString strIP, BOOL bAcceptSameIP)
|
{
|
m_nListenPort = nPort;
|
m_bAcceptSameIP = bAcceptSameIP;
|
return CIOCPController::InitNetwork(Mode, nSocketCount, nPort, strIP);
|
}
|
|
CNetPacket* CNetServer::GetPacket()
|
{
|
if (!m_pPacket)
|
return NULL;
|
|
CNetPacket* pPacket = NULL;
|
EnterCriticalSection(&m_csPacket);
|
|
int nCount = 0;
|
do
|
{
|
pPacket = &m_pPacket[m_nPacketIdx];
|
m_nPacketIdx = ++m_nPacketIdx % m_nTotalPacketCount;
|
if (!pPacket->IsUsing())
|
{
|
pPacket->LockPacket();
|
break;
|
}
|
Sleep(0);
|
if (++nCount > 1000)
|
{
|
LeaveCriticalSection(&m_csPacket);
|
return NULL;
|
}
|
} while(TRUE);
|
|
pPacket->ResetValues();
|
|
LeaveCriticalSection(&m_csPacket);
|
|
return pPacket;
|
}
|
|
BOOL CNetServer::DisconnectClient(int nModuleNo)
|
{
|
BOOL bRet = FALSE;
|
EnterCriticalSection(&m_csContext);
|
for (int i = 0; i < m_nClientCount; i++)
|
{
|
if (m_pClientJoiner[i].GetModuleNo() == nModuleNo)
|
{
|
CloseSocket(m_pClientJoiner[i].GetSocketContext(), FALSE, FALSE);
|
m_pClientJoiner[i].Reset();
|
bRet = TRUE;
|
break;
|
}
|
}
|
LeaveCriticalSection(&m_csContext);
|
|
return bRet;
|
}
|
|
// Server SocketÀÌ Á¢¼ÓÀ» Çã¿ëÇßÀ» ¶§ È£ÃâÇÏ´Â ÇÔ¼ö.
|
int CNetServer::AcceptedSocket(pPerSocketContext pCtx, ULONG ulIP, int nPort)
|
{
|
if (nPort != m_nListenPort)
|
{
|
NoticeMsg("Accepte ÁÖ¼Ò°¡ À߸øµÊ. %d - %d", m_nListenPort, nPort);
|
return FALSE;
|
}
|
|
int nRet = -1;
|
if(m_bAcceptSameIP == FALSE)
|
{
|
for (int i = 0; i < m_nClientCount; i++)
|
{
|
if (m_pClientJoiner[i].GetClientIP() == ulIP)
|
{
|
NoticeMsg("AcceptedSocket : Close Socket : %d, %u", i, ulIP);
|
pCtx = m_pClientJoiner[i].GetSocketContext();
|
nRet = 0;
|
break;
|
}
|
}
|
}
|
|
if (nRet == -1)
|
{
|
for (int i = 0; i < m_nClientCount; i++)
|
{
|
if (m_pClientJoiner[i].GetClientIP() == -1)
|
{
|
m_pClientJoiner[i].SetClientIP(ulIP);
|
m_pClientJoiner[i].SetSocketContext(pCtx);
|
|
nRet = 1;
|
break;
|
}
|
}
|
}
|
|
// Á¢¼Ó °ú´Ù.
|
if (nRet == -1)
|
NoticeMsg("Á¢¼Ó °ú´Ù·Î Á¾·á, ListenPort %d, CurPort %d\n", m_nListenPort, nPort);
|
|
return nRet;
|
}
|
|
// SocketÀÌ ²÷¾îÁ³À½À» ¾Ë·ÁÁÖ±â À§ÇÑ ÇÔ¼ö
|
void CNetServer::SocketClosed(pPerSocketContext pSocketCtx)
|
{
|
int nModuleNo;
|
for (int i = 0; i < m_nClientCount; i++)
|
{
|
if (reinterpret_cast<__int64>(m_pClientJoiner[i].GetSocketContext()) == reinterpret_cast<__int64>(pSocketCtx))
|
{
|
nModuleNo = m_pClientJoiner[i].GetModuleNo();
|
m_pClientJoiner[i].Reset();
|
m_pN2M->IOCPNet2P_Disconnected(m_Clientint, nModuleNo);
|
|
break;
|
}
|
}
|
}
|
|
// Client SocketÀÌ Á¢¼ÓµÇ¾úÀ» ¶§ È£ÃâÇÏ´Â ÇÔ¼ö
|
BOOL CNetServer::ConnectedSocket(pPerSocketContext pSocketCtx)
|
{
|
return TRUE;
|
}
|
|
// Socket¿¡¼ Receive°¡ ¿Ï·áµÇ¾úÀ» ¶§ CIOCPController¿¡¼ È£ÃâÇÏ´Â ÇÔ¼ö - Data Parseing
|
BOOL CNetServer::RecvCompleted(pPerSocketContext pSocketCtx, DWORD dwBytes)
|
{
|
// ¹öÆÛ°¡ ºô ¶§±îÁö ó¸®.
|
WSABUF* pBuf = pSocketCtx->recvContext->GetLockedBuffer();
|
if (!pBuf)
|
{
|
NoticeMsg("Packet Lost :: Buf is not Available. Buf - %d", reinterpret_cast<__int64>(pBuf));
|
return TRUE;
|
}
|
|
int nRead = 0;
|
DWORD dwCompBytes = 0;
|
DWORD dwCurrentBytes = dwBytes + (MAX_BUFFER_SIZE - pBuf->len);
|
pBuf->buf = pSocketCtx->recvContext->GetBulkBuffer();
|
|
int nPacketCount = 0, nOldPacket = 0;;
|
while (TRUE)
|
{
|
if (dwCurrentBytes < PACKET_HEADERSIZE) // ÃÖ¼Ò ÆÐŶ Å©±â.
|
{
|
// ÆÐŶÀ» ´Ù ¹ÞÁö ¸øÇÏ¸é ´õ ¹Þ´Â´Ù.
|
if (dwCompBytes > 0 && dwCurrentBytes > 0)
|
{
|
// NoticeMsg("ó¸®ÇÑ ºÎºÐ »èÁ¦ 1 Recv %d, Cur %d, Comp %d", dwBytes, dwCurrentBytes, dwCompBytes);
|
char* strTemp = new char[dwCurrentBytes + 1];
|
ZeroMemory(strTemp, dwCurrentBytes + 1);
|
memcpy(strTemp, pBuf->buf, dwCurrentBytes);
|
pBuf->buf = pSocketCtx->recvContext->GetBulkBuffer();
|
ZeroMemory(pBuf->buf, MAX_BUFFER_SIZE + 1);
|
memcpy(pBuf->buf, strTemp, dwCurrentBytes);
|
if (strTemp)
|
{
|
delete [] strTemp;
|
strTemp = NULL;
|
}
|
dwCompBytes = 0;
|
}
|
// NoticeMsg("Çì´õÆÐŶº¸´Ù ÀÛÀ½ Recv %d, Cur %d, Comp %d", dwBytes, dwCurrentBytes, dwCompBytes);
|
pBuf->buf = pSocketCtx->recvContext->GetBulkBuffer() + dwCurrentBytes;
|
pBuf->len = MAX_BUFFER_SIZE - dwCurrentBytes;
|
return FALSE;
|
}
|
|
CNetPacket* pPacket = GetPacket();
|
if (!pPacket)
|
{
|
NoticeMsg("RecvCompleted :: Packet is not Available. pPacket - %d", reinterpret_cast<__int64>(pPacket));
|
break;
|
}
|
|
nRead = pPacket->Read_PacketHeader(pBuf);
|
if (nRead == 0)
|
{
|
NoticeMsg("Packet Lost :: Read Packet Header. Read - %d", nRead);
|
pPacket->UnlockPacket();
|
return TRUE;
|
}
|
if (pPacket->GetVersion() != m_sVersion)
|
{
|
NoticeMsg("Packet Header :: Version Mismatch!! Set %d, Packet %d, Recv %d, Cur %d, Len %d, PktCount %d, Pkt %d, Comp %d, Size %d"
|
, m_sVersion, pPacket->GetVersion(), dwBytes, dwCurrentBytes, pBuf->len, nPacketCount, nOldPacket, dwCompBytes, pPacket->GetSize());
|
pPacket->UnlockPacket();
|
return TRUE;
|
}
|
if (pPacket->GetSize() <= 0) // ¿¹¿Üó¸® - ¹ÞÀº µ¥ÀÌÅÍ´Â Áö¿ö¹ö¸®°í ´Ù½Ã ¹Þ´Â´Ù.
|
{
|
NoticeMsg("Packet Lost :: Exception in Size - Size %d, Code %d, Module %d", pPacket->GetSize(), pPacket->GetPacketCode(), pPacket->GetModuleNo());
|
pPacket->UnlockPacket();
|
return TRUE;
|
}
|
|
if (dwCurrentBytes >= (DWORD)pPacket->GetSize()) // ±æÀÌ Ã¼Å©.
|
{
|
if (pPacket->GetSize() > PACKET_HEADERSIZE)
|
{
|
nRead = pPacket->Read_PacketBody(pBuf->buf + nRead);
|
if (nRead == -1)
|
{
|
NoticeMsg("Packet Lost :: Read Packet Body. Read - %d, Cur %d, Size %d", nRead, dwCurrentBytes, pPacket->GetSize());
|
pPacket->UnlockPacket();
|
return TRUE;
|
}
|
else if (nRead == -2)
|
{
|
NoticeMsg("Packet Lost :: Read Packet Body. Exception - %d, Cur %d, Size %d", nRead, dwCurrentBytes, pPacket->GetSize());
|
pPacket->UnlockPacket();
|
return TRUE;
|
}
|
}
|
|
// Context¿Í Module ¿¬°áÀ» À§ÇØ pSocketCtx¸¦ ³Ñ±ä´Ù.
|
if (m_pN2M)
|
m_pN2M->IOCPNet2P_Received(m_Clientint, pPacket, reinterpret_cast<__int64>(pSocketCtx));
|
nPacketCount++;
|
nOldPacket = pPacket->GetPacketCode();
|
if (dwCurrentBytes == (DWORD)pPacket->GetSize())
|
{
|
pPacket->UnlockPacket();
|
return TRUE; // ¸ðµç ¹öÆÛ¸¦ ´Ù ó¸®Çß´Ù.
|
}
|
|
// ¹öÆÛ°¡ ³²¾ÆÀÖÀ¸¸é ´Ù½Ã ó¸®ÇÑ´Ù.
|
dwCompBytes += (DWORD)pPacket->GetSize();
|
dwCurrentBytes -= (DWORD)pPacket->GetSize();
|
pBuf->buf = pBuf->buf + pPacket->GetSize();
|
pPacket->UnlockPacket();
|
}
|
else
|
{
|
if (dwCompBytes > 0 && dwCurrentBytes > 0)
|
{
|
// NoticeMsg("ó¸®ÇÑ ºÎºÐ »èÁ¦ 2 Recv %d, Pak %d, Cur %d, Comp %d, PktSize %d", dwBytes, pPacket->GetSize(), dwCurrentBytes, dwCompBytes, pPacket->GetSize());
|
char* strTemp = new char[dwCurrentBytes + 1];
|
ZeroMemory(strTemp, dwCurrentBytes + 1);
|
memcpy(strTemp, pBuf->buf, dwCurrentBytes);
|
pBuf->buf = pSocketCtx->recvContext->GetBulkBuffer();
|
ZeroMemory(pBuf->buf, MAX_BUFFER_SIZE + 1);
|
memcpy(pBuf->buf, strTemp, dwCurrentBytes);
|
if (strTemp)
|
{
|
delete [] strTemp;
|
strTemp = NULL;
|
}
|
|
// CNetPacket* pTmpPacket = GetPacket();
|
// if (pTmpPacket)
|
// {
|
// nRead = pTmpPacket->Read_PacketHeader(pBuf);
|
// NoticeMsg("»èÁ¦ ÈÄ Çì´õ Version %d, Code %d, Size %d", pTmpPacket->GetVersion(), pTmpPacket->GetPacketCode(), pTmpPacket->GetSize());
|
// pTmpPacket->UnlockPacket();
|
// }
|
}
|
// NoticeMsg("¸ðÀÚ¶ó¼ ´Ù½Ã ¹Þ±â Recv %d, Pak %d, Cur %d, Comp %d", dwBytes, pPacket->GetSize(), dwCurrentBytes, dwCompBytes);
|
pBuf->buf = pSocketCtx->recvContext->GetBulkBuffer() + dwCurrentBytes;
|
pBuf->len = MAX_BUFFER_SIZE - dwCurrentBytes;
|
pPacket->UnlockPacket();
|
return FALSE;
|
}
|
}
|
|
return TRUE;
|
}
|
|
// SocketÀ» ÅëÇØ Send°¡ ¿Ï·áµÇ¾úÀ» ¶§ CIOCPController¿¡¼ È£ÃâÇÏ´Â ÇÔ¼ö. - ÈÄó¸®
|
BOOL CNetServer::SendCompleted(pPerSocketContext pSocketCtx, DWORD dwBytes)
|
{
|
// //TRACE("SendCompleted. Trans %d - Len %d\n", dwBytes, pSocketCtx->sendContext->GetLen());
|
return FALSE;
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
// Packet Send
|
|
CNetJoiner* CNetServer::GetJoinerUser(int nModuleNo)
|
{
|
// Client ã±â
|
if (nModuleNo < 0 || nModuleNo >= m_nClientCount)
|
return NULL;
|
|
CNetJoiner* pClientJoiner = NULL;
|
for (int i = 0; i < m_nClientCount; i++)
|
{
|
if (m_pClientJoiner[i].GetSocketContext() && m_pClientJoiner[i].GetModuleNo() == nModuleNo)
|
{
|
pClientJoiner = &m_pClientJoiner[i];
|
break;
|
}
|
}
|
|
return pClientJoiner;
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
// Packet Send.
|
BOOL CNetServer::InvokeToClient(int nType, SHORT sResult)
|
{
|
BOOL bRet = TRUE;
|
for (int i = 0; i < m_nClientCount; i++)
|
{
|
if (!SendToClient(i, nType, sResult))
|
bRet = FALSE;
|
}
|
|
return bRet;
|
}
|
|
|
|
BOOL CNetServer::InvokeToClient(int nType, SHORT sResult, CNetPacket* pPacket)
|
{
|
BOOL bRet = TRUE;
|
for (int i = 0; i < m_nClientCount; i++)
|
{
|
if (!SendToClient(i, nType, sResult, pPacket))
|
bRet = FALSE;
|
}
|
|
return bRet;
|
}
|
|
BOOL CNetServer::InvokeToClient(int nType, SHORT sResult, SHORT sPacketIdx, CNetPacket* pPacket)
|
{
|
BOOL bRet = TRUE;
|
for (int i = 0; i < m_nClientCount; i++)
|
{
|
if (!SendToClient(i, nType, sResult, sPacketIdx, pPacket))
|
bRet = FALSE;
|
}
|
|
return bRet;
|
}
|
|
BOOL CNetServer::SendToClient(int nModuleNo, int nType, SHORT sResult)
|
{
|
return SendToClient(nModuleNo, nType, sResult, -1, NULL);
|
}
|
|
BOOL CNetServer::SendToClient(int nModuleNo, int nType, SHORT sResult, CNetPacket* pPacket)
|
{
|
return SendToClient(nModuleNo, nType, sResult, -1, pPacket);
|
}
|
|
BOOL CNetServer::SendToClient(int nModuleNo, int nType, SHORT sResult, SHORT sPacketIdx, CNetPacket* pPacket)
|
{
|
CNetJoiner* pClientJoiner = GetJoinerUser(nModuleNo);
|
|
int nRet = 0;
|
if (pClientJoiner && pClientJoiner->GetSocketContext())
|
{
|
pPerSocketContext pCtx = pClientJoiner->GetSocketContext();
|
WSABUF* pWsaBuf;
|
int nCount = 0;
|
while (TRUE)
|
{
|
pWsaBuf = pClientJoiner->GetSendBuffer();
|
if (!pWsaBuf)
|
Sleep(0);
|
else
|
break;
|
}
|
|
if(pWsaBuf->buf == NULL)
|
return FALSE;
|
|
// Buffer¸¦ ä¿î´Ù.
|
int i;
|
int nWriteSize = 0;
|
SHORT sPacketIdx = 0;
|
|
// Header ä¿ì±â.
|
// memcpy(pWsaBuf->buf + nWriteSize, &nSize, sizeof(int));
|
nWriteSize += sizeof(int);
|
memcpy(pWsaBuf->buf + nWriteSize, &m_sNetworkCode, sizeof(SHORT));
|
nWriteSize += sizeof(SHORT);
|
memcpy(pWsaBuf->buf + nWriteSize, &m_sVersion, sizeof(SHORT));
|
nWriteSize += sizeof(SHORT);
|
memcpy(pWsaBuf->buf + nWriteSize, &nType, sizeof(int));
|
nWriteSize += sizeof(int);
|
memcpy(pWsaBuf->buf + nWriteSize, &sPacketIdx, sizeof(SHORT));
|
nWriteSize += sizeof(SHORT);
|
memcpy(pWsaBuf->buf + nWriteSize, &sResult, sizeof(SHORT));
|
nWriteSize += sizeof(SHORT);
|
memcpy(pWsaBuf->buf + nWriteSize, &nModuleNo, sizeof(int));
|
nWriteSize += sizeof(int);
|
|
// Body ä¿ì±â
|
if (pPacket)
|
{
|
int nCount = pPacket->GetShortCount();
|
memcpy(pWsaBuf->buf + nWriteSize, &nCount, sizeof(int));
|
nWriteSize += sizeof(int);
|
short sValue;
|
for (i = 0; i < nCount; i++)
|
{
|
sValue = pPacket->GetShort(i);
|
memcpy(pWsaBuf->buf + nWriteSize, &sValue, sizeof(short));
|
nWriteSize += sizeof(short);
|
}
|
|
nCount = pPacket->GetIntCount();
|
memcpy(pWsaBuf->buf + nWriteSize, &nCount, sizeof(int));
|
nWriteSize += sizeof(int);
|
int nValue;
|
for (i = 0; i < nCount; i++)
|
{
|
nValue = pPacket->GetInt(i);
|
memcpy(pWsaBuf->buf + nWriteSize, &nValue, sizeof(int));
|
nWriteSize += sizeof(int);
|
}
|
|
nCount = pPacket->GetDoubleCount();
|
memcpy(pWsaBuf->buf + nWriteSize, &nCount, sizeof(int));
|
nWriteSize += sizeof(int);
|
double dValue;
|
for (i = 0; i < nCount; i++)
|
{
|
dValue = pPacket->GetDouble(i);
|
memcpy(pWsaBuf->buf + nWriteSize, &dValue, sizeof(double));
|
nWriteSize += sizeof(double);
|
}
|
|
CString String;
|
int nLength;
|
nCount = pPacket->GetStringCount();
|
memcpy(pWsaBuf->buf + nWriteSize, &nCount, sizeof(int));
|
nWriteSize += sizeof(int);
|
for (i = 0; i < nCount; i++)
|
{
|
String = pPacket->GetString(i);
|
|
char * str_Data = NULL;
|
#ifdef _UNICODE
|
int length = WideCharToMultiByte(CP_ACP, 0, String.GetBuffer(), -1, NULL, 0, NULL,NULL);
|
str_Data = new char[length];
|
WideCharToMultiByte(CP_ACP, 0, String.GetBuffer(), -1, str_Data, length, NULL, NULL);
|
#else
|
int length = String.GetLength();
|
str_Data = new char[length+1];
|
memcpy(str_Data, String.GetBuffer(), sizeof(char)*length);
|
str_Data[length] = NULL;
|
#endif
|
if (str_Data==NULL)
|
{
|
continue;
|
}
|
|
nLength = String.GetLength();
|
memcpy(pWsaBuf->buf + nWriteSize, &nLength, sizeof(int));
|
nWriteSize += sizeof(int);
|
|
if (nLength > 0)
|
{
|
memcpy(pWsaBuf->buf + nWriteSize, str_Data, nLength);
|
nWriteSize += nLength;
|
}
|
|
delete [] str_Data;
|
}
|
|
nLength = pPacket->GetBufferSize();
|
memcpy(pWsaBuf->buf + nWriteSize, &nLength, sizeof(int));
|
nWriteSize += sizeof(int);
|
if (nLength > 0)
|
{
|
memcpy(pWsaBuf->buf + nWriteSize, pPacket->GetBuffer(), nLength);
|
nWriteSize += nLength;
|
}
|
pPacket->UnlockPacket();
|
}
|
memcpy(pWsaBuf->buf, &nWriteSize, sizeof(int));
|
pWsaBuf->len = nWriteSize;
|
|
nRet = SendPost(pClientJoiner->GetSocketContext());
|
if (nRet == 2)
|
NoticeMsg("0 Bytes Sent : %d", nModuleNo);
|
}
|
else
|
{
|
if (pPacket)
|
pPacket->UnlockPacket();
|
}
|
|
return nRet;
|
}
|