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