#include "StdAfx.h"
|
#include "IOCPController.h"
|
|
BOOL CIOCPController::m_bIsStartUp = FALSE;
|
|
CIOCPController::CIOCPController(void)
|
{
|
InitializeCriticalSection(&m_csContext);
|
|
// µ¿±âÈ º¯¼ö Ãß°¡
|
m_nExit = FALSE;
|
|
m_pPerSocketCtxMemPool = NULL;
|
m_pRecvMemPool = NULL;
|
m_pSendMemPool = NULL;
|
|
ZeroMemory(m_strFileName, MAX_PATH);
|
m_nLogYear = 0;
|
m_nLogMonth = 0;
|
m_nLogDay = 0;
|
|
m_nPort = 0;
|
m_strIP = _T("");
|
|
m_pSocketCtx = NULL;
|
m_bReconnect = FALSE;
|
m_bConnected = FALSE;
|
|
m_hMutexLog = CreateMutex(NULL, FALSE, _T("Mutex_IOCPLog"));
|
|
m_EventExitConnectThread = NULL;
|
|
for(int i=0; i<10; i++)
|
m_strIPAddr[i].Empty();
|
|
}
|
|
CIOCPController::~CIOCPController(void)
|
{
|
// DeinitNetwork´Â »ó¼Ó¹Þ´Â ÃÖÁ¾ ¼¹ö/Ŭ¶óÀÌ¾ðÆ® ¿¡¼ ¸ÕÀú ¼±ÇàÇÏ¿© ÇØÁà¾ßÇÑ´Ù.
|
// ÀÌÀ¯ : ÃÖÁ¾ »ó¼Ó´Ü¿¡¼µµ ¶Ç Net_Receive µî°ú °°ÀÌ °¡»óÇÔ¼ö¸¦ Áö¿øÇϱ⠶§¹®¿¡ ÃÖÁ¾ »ó¼Ó´ÜÀÌ ¸ÕÀú ¼Ò¸êµÇ¸é(¶Ç´Â ¼Ò¸ê Áß)ÀÌ¸é ¿öÄ¿ ¾²·¹µå¿¡¼ IO ó¸®ÇÏ´Â µµÁß¿¡
|
// Net_Receive µî¿¡¼ SendMessage µî°ú °°Àº µ¿±âÈ Äڵ尡 Á¸ÀçÇϸé ÇàÀÌ °É¸®°í ´Ù¿îµÇ°Ô µÈ´Ù.
|
//DeinitNetwork();
|
|
m_nExit = TRUE;
|
|
// ¿öÄ¿¾²·¹µå¸¦ ¸ÕÀú Á×µµ·Ï µ¿±âÈ ÇÑ´Ù.
|
// ÀÌÀ¯ : À§¿Í °°Àº ÀÌÀ¯·Î ÃÖÁ¾ »ó¼ÓÀÚ°¡ Handle¸¦ ÀÒ¾î¹ö¸®´Â ÀÏÀ» ¸·±â À§Çؼ
|
if(m_EventExitWorkerThread != NULL)
|
WaitForSingleObject(m_EventExitWorkerThread,INFINITE);
|
|
if (m_pPerSocketCtxMemPool){ delete m_pPerSocketCtxMemPool; m_pPerSocketCtxMemPool = NULL; }
|
if (m_pRecvMemPool){ delete m_pRecvMemPool; m_pRecvMemPool = NULL; }
|
if (m_pSendMemPool){ delete m_pSendMemPool; m_pSendMemPool = NULL; }
|
|
CloseHandle(m_hMutexLog);
|
m_hMutexLog = NULL;
|
|
if(m_EventExitConnectThread != NULL)
|
{
|
CloseHandle(m_EventExitConnectThread);
|
m_EventExitConnectThread = NULL;
|
}
|
DeleteCriticalSection(&m_csContext);
|
//TRACE("CIOCPController::~CIOCPController(void) \n");
|
}
|
|
/*!
|
* \brief
|
* ¼ÒÄÏ ÃʱâÈ ÇÔ¼ö
|
*
|
* \returns
|
* ½ÇÆÐ : FALSE, ¼º°ø : TRUE
|
*
|
*
|
* ¼ÒÄÏÀ» ÃʱâÈÇϰí ÇöÀç È£½ºÆ®ÀÇ ¾ÆÀÌÇǸ¦ ¼³Á¤ÇÑ´Ù.
|
*
|
* \remarks
|
* Write remarks for StartUp here.
|
*
|
* \see
|
* Separate items with the '|' character.
|
*/
|
BOOL CIOCPController::StartUp()
|
{
|
// ¼ÒÄÏ ÃʱâÈ Ã³¸®
|
if (!m_bIsStartUp)
|
{
|
WSADATA wsd;
|
if(WSAStartup(MAKEWORD(2,2), &wsd) != 0)
|
{
|
return FALSE;
|
}
|
if (LOBYTE( wsd.wVersion ) != 2 || HIBYTE( wsd.wVersion ) != 2 )
|
{
|
WSACleanup( );
|
return FALSE;
|
}
|
m_bIsStartUp = TRUE;
|
}
|
|
CHAR chName[255];
|
CHAR chAddr[128];
|
PHOSTENT pHostEntry;
|
// IN_ADDR inAddr;
|
CStringA strCurIP;
|
|
strCurIP = _T("");
|
|
if( gethostname( chName, 255 ) != 0 ){ }
|
else
|
{
|
if( ( pHostEntry = gethostbyname( chName ) ) != NULL )
|
{
|
for (int i=0; pHostEntry->h_addr_list[i]; i++)
|
{
|
if(i >= 10) break;
|
|
m_strIPAddr[i].Format(_T("%d.%d.%d.%d")
|
, ((PUCHAR)pHostEntry->h_addr_list[i])[0]
|
, ((PUCHAR)pHostEntry->h_addr_list[i])[1]
|
, ((PUCHAR)pHostEntry->h_addr_list[i])[2]
|
, ((PUCHAR)pHostEntry->h_addr_list[i])[3]);
|
}
|
// memcpy( &inAddr, pHostEntry->h_addr, 4 );
|
// memcpy(chAddr, inet_ntoa( inAddr ), 16);
|
}
|
}
|
|
strCurIP = (CStringA)chAddr;
|
|
m_strIP = strCurIP;
|
|
return TRUE;
|
}
|
|
/*!
|
* \brief
|
* ¼ÒÄÏ ÇØÁ¦ ÇÔ¼ö
|
*
|
* \returns
|
* TRUE
|
*
|
*
|
* ¼ÒÄÏÀÇ »ç¿ëÀ» Á¾·áÇÏ°í ¹ÝȯÇÑ´Ù.
|
*
|
* \remarks
|
* Write remarks for CleanUp here.
|
*
|
* \see
|
* Separate items with the '|' character.
|
*/
|
BOOL CIOCPController::CleanUp()
|
{
|
// ¼ÒÄÏ »ç¿ë ³¡!!!!!
|
if (m_bIsStartUp)
|
WSACleanup();
|
|
m_bIsStartUp = FALSE;
|
|
return TRUE;
|
}
|
|
/*!
|
* \brief
|
* ³×Æ®¿öÅ© ÃʱâÈ ÇÔ¼ö
|
*
|
* \param Mode
|
* ³×Æ®¿öÅ© ¸ðµå ( ¼¹ö , Ŭ¶óÀÌ¾ðÆ® ¸ðµå )
|
*
|
* \param nSocketCount
|
* »ý¼ºÇÒ ¼ÒÄÏÀÇ °³¼ö ( ¼¹ö : ÃÖ´ë Ŭ¶óÀÌ¾ðÆ® °³¼ö, Ŭ¶óÀÌ¾ðÆ® : 1)
|
*
|
* \param nPort
|
* Æ÷Æ®
|
*
|
* \param strIP
|
* IPÁÖ¼Ò
|
*
|
* \param nWorkerThreadNum
|
* IOCP ¿öÄ¿ ¾²·¹µå °³¼ö ¼³Á¤ ( ±âº»Àº 2 * ÇÁ·Î¼¼¼¼ö + 1
|
*
|
* \returns
|
* ¼º°ø : TRUE, ½ÇÆÐ : FALSE
|
*
|
*/
|
BOOL CIOCPController::InitNetwork(NetworkMode Mode, int nSocketCount, int nPort, CString strIP, int nWorkerThreadNum)
|
{
|
//TRACE("--- IOCP::Init() - Start! \n");
|
if (!m_bIsStartUp)
|
return FALSE;
|
|
if (!strIP.IsEmpty())
|
m_strIP = strIP;
|
if (nPort > 0)
|
m_nPort = nPort;
|
|
if (m_nPort == 0)
|
return FALSE;
|
SOCKADDR_IN serverSockAddr;
|
|
/********************************************************************************/
|
// Memory Pool ¸¸µé±â!!
|
/********************************************************************************/
|
if (m_pPerSocketCtxMemPool){ delete m_pPerSocketCtxMemPool; m_pPerSocketCtxMemPool = NULL; }
|
if (m_pRecvMemPool){ delete m_pRecvMemPool; m_pRecvMemPool = NULL; }
|
if (m_pSendMemPool){ delete m_pSendMemPool; m_pSendMemPool = NULL; }
|
|
m_pPerSocketCtxMemPool = new CMemPooler<PerSocketContext>(nSocketCount * 2); //nSocketCount * 2 -> Block °³¼ö
|
m_pRecvMemPool = new CMemPooler<PerIoContext>(nSocketCount * 2);
|
m_pSendMemPool = new CMemPooler<PerIoContext>(nSocketCount * 2);
|
|
if (!m_pPerSocketCtxMemPool || !m_pRecvMemPool || !m_pSendMemPool)
|
{
|
//TRACE("IOCP::Init() - Create Memory Pool Failed \n");
|
return FALSE;
|
}
|
|
m_NetMode = Mode;
|
if (Mode == ServerMode)
|
{
|
m_bConnected = TRUE;
|
|
/********************************************************************************/
|
// Listen Socket »ý¼º - Overlapped IO »ç¿ë
|
/********************************************************************************/
|
if(m_ListenSocket != NULL)
|
closesocket(m_ListenSocket);
|
m_ListenSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
|
if(m_ListenSocket == INVALID_SOCKET)
|
{
|
//TRACE("IOCP::Init() - Listen Socket Creation Failed : %d \n", WSAGetLastError());
|
return FALSE;
|
}
|
|
int nZero = 1;
|
if (SOCKET_ERROR == setsockopt(m_ListenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&nZero, sizeof(int)))
|
{
|
//TRACE("IOCP::Init() - setsockopt Fail : %d \n", WSAGetLastError());
|
closesocket(m_ListenSocket);
|
m_ListenSocket = NULL;
|
return FALSE;
|
}
|
|
|
serverSockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
serverSockAddr.sin_family = AF_INET;
|
serverSockAddr.sin_port = htons((short)m_nPort);
|
|
// Bind
|
if(bind(m_ListenSocket, (LPSOCKADDR)&serverSockAddr, sizeof(serverSockAddr)))
|
{
|
//TRACE("IOCP::Init() - Bind Failed : %d \n", WSAGetLastError());
|
closesocket(m_ListenSocket);
|
m_ListenSocket = NULL;
|
return FALSE;
|
}
|
|
// Listen
|
if(SOCKET_ERROR == listen(m_ListenSocket, SOMAXCONN))
|
{
|
//TRACE("IOCP::Init() - Change to Listen Mode Error : %d\n", WSAGetLastError());
|
closesocket(m_ListenSocket);
|
m_ListenSocket = NULL;
|
return FALSE;
|
}
|
}
|
else if (Mode == ClientMode)
|
{
|
m_ListenSocket = INVALID_SOCKET;
|
}
|
|
/********************************************************************************/
|
// IOCP ÃʱâÈ Ã³¸®
|
// m_hIOCP=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,nMaxNumberOfConcurrentThreads)
|
/********************************************************************************/
|
|
int ErrCode;
|
if (!Create(0, &ErrCode))
|
{
|
//TRACE("IOCP::Init() - Create IO Completion Port Error: %d \n", ErrCode);
|
return FALSE;
|
}
|
|
/********************************************************************************/
|
// Thread Pool À» »ý¼º!
|
// BEGINTHREADEX(NULL,0,IocpWorkerThreadStartingPoint,piProcessThread,0,&dwThreadId)
|
/********************************************************************************/
|
if (!CreateThreadPool(this,nWorkerThreadNum))
|
{
|
//TRACE("IOCP::Init() - Create Thread Pool Failed \n");
|
return FALSE;
|
}
|
|
/********************************************************************************/
|
// Accept Thread »ý¼º.
|
/********************************************************************************/
|
if (Mode == ServerMode)
|
{
|
DWORD dwThreadId;
|
HANDLE hAccept = CreateThread(NULL, 0, AcceptThread, this, 0, &dwThreadId);
|
CloseHandle(hAccept);
|
hAccept = NULL;
|
}
|
|
return TRUE;
|
}
|
|
|
/*!
|
* \brief
|
* Accept ÀÛ¾÷ ó¸®!!
|
*
|
*
|
* Ŭ¶óÀÌ¾ðÆ®·ÎºÎÅÍÀÇ Á¢¼Ó ¿¬°á ¿äûÀ» ó¸®ÇÏ´Â ÇÔ¼ö
|
*
|
|
*/
|
void CIOCPController::AcceptProcess()
|
{
|
int ErrCode = 0;
|
|
int sockaddr_size = sizeof(SOCKADDR_IN);
|
SOCKADDR_IN clientsockaddr;
|
SOCKET clientsocket = INVALID_SOCKET;
|
pPerSocketContext pPerSocketCtx = NULL;
|
|
|
//TRACE("IOCP::AcceptProcess() - Accept Process Start \n");
|
|
BOOL bLoop = TRUE;
|
while(bLoop == TRUE)
|
{
|
Sleep(1);
|
|
__try
|
{
|
clientsocket = INVALID_SOCKET;
|
pPerSocketCtx = NULL;
|
|
/********************************************************************************/
|
// Client·ÎºÎÅÍ accept
|
/********************************************************************************/
|
clientsocket=accept(m_ListenSocket,(LPSOCKADDR)&clientsockaddr, &sockaddr_size);
|
if(clientsocket==INVALID_SOCKET)
|
{
|
// ¸®½¼ ¼ÒÄÏÀ» Ŭ·ÎÁî Çϸé ÀÌ ¿¡·¯°¡ ³ª¿À¹Ç·Î
|
// ÀÌ ¿¡·¯½Ã¿¡ Accept ·çÇÁ¸¦ ºüÁ®³ª°£´Ù.
|
if(WSAGetLastError()==WSAEINTR || WSAGetLastError() == WSAENOTSOCK || WSAGetLastError() == WSANOTINITIALISED)
|
{
|
//TRACE("IOCP::AcceptProcess() - Accept Process End : %d\n",WSAGetLastError() );
|
bLoop = FALSE;
|
return; // abnormalterminate ½ÇÇà
|
}
|
|
//TRACE("Accepting Client Error: %d\n ",WSAGetLastError());
|
|
__leave;
|
}
|
//TRACE("Client( IP: %s, Port: %d, Socket %d ) Connected\n",inet_ntoa(clientsockaddr.sin_addr),ntohs(clientsockaddr.sin_port), clientsocket);
|
|
int nZero=0;
|
if(SOCKET_ERROR==setsockopt(clientsocket,SOL_SOCKET,SO_RCVBUF,(const char*)&nZero,sizeof(int)))
|
{
|
//TRACE("Change Buffer Size Error, %d\n",WSAGetLastError());
|
return;
|
}
|
nZero=0;
|
if(SOCKET_ERROR==setsockopt(clientsocket,SOL_SOCKET,SO_SNDBUF,(const char*)&nZero,sizeof(int)))
|
{
|
//TRACE("Change Buffer Size Error, %d\n",WSAGetLastError());
|
return;
|
}
|
|
/********************************************************************************/
|
// ¼ÒÄÏ ÄÁÅØ½ºÆ® ÇÒ´ç -> Completion Key
|
// Per Socket Context ¸Þ¸ð¸® ÇÒ´ç
|
/********************************************************************************/
|
pPerSocketCtx = AllocPerSocketContext(clientsocket);
|
if(pPerSocketCtx == NULL)
|
{
|
//TRACE("Socket Context Allocation Error\n");
|
return;
|
}
|
|
/********************************************************************************/
|
// IOCP Ä¿³Î °´Ã¼¿Í ¿¬°á
|
/********************************************************************************/
|
if (!Associate(clientsocket, reinterpret_cast<ULONG_PTR>(pPerSocketCtx), &ErrCode))
|
{
|
//TRACE("IOCP::AcceptProcess() - Associating Error: %d\n ", ErrCode);
|
return;
|
}
|
/********************************************************************************/
|
// Ãʱâ Recv ¿äû
|
/********************************************************************************/
|
int nRet = AcceptedSocket(pPerSocketCtx, clientsockaddr.sin_addr.S_un.S_addr, m_nPort);
|
if (nRet == 0) // ÀÌ¹Ì Á¢¼Ó.
|
{
|
//TRACE("IOCP::AcceptProcess() - Already Accepted! SocketContext[%X] ÀÌÀü ÄÁÅØ½ºÆ®¿Í »õ·Î¿î ÄÁÅØ½ºÆ®¸¦ ¸ðµÎ Áö¿î´Ù. !!!!!!!!\n",pPerSocketCtx);
|
return;
|
|
}
|
else if (nRet == -1)
|
{
|
//TRACE("IOCP::AcceptProcess() - Accept Socket Error! \n");
|
return;
|
}
|
else
|
{
|
BOOL bRet = RecvPost(pPerSocketCtx);
|
if(bRet == FALSE)
|
{
|
//TRACE("Init RecvPost Error\n");
|
return;
|
}
|
else
|
{
|
//TRACE("Init RevcPost Success\n");
|
__leave;
|
}
|
}
|
|
}
|
__finally
|
{
|
if (AbnormalTermination() == TRUE)
|
{
|
// ºñÁ¤»ó Á¾·á
|
//TRACE("IOCP::AcceptProcess() - Called CloseSocket() in __finally! \n");
|
if (pPerSocketCtx != NULL)
|
CloseSocket(pPerSocketCtx,FALSE,FALSE);
|
|
if(clientsocket != INVALID_SOCKET)
|
{
|
closesocket(clientsocket);
|
clientsocket = INVALID_SOCKET;
|
}
|
}
|
else
|
{
|
// Á¤»ó»óȲ
|
|
}
|
}
|
}
|
}
|
|
DWORD __stdcall CIOCPController::AcceptThread(PVOID pvParam)
|
{
|
CIOCPController* pCont = static_cast<CIOCPController*>(pvParam);
|
pCont->AcceptProcess();
|
|
return 0;
|
}
|
|
/********************************************************************************/
|
//
|
/********************************************************************************/
|
/*!
|
* \brief
|
* Connect ÀÛ¾÷ ó¸® ÇÔ¼ö
|
*
|
* \param bReconnect
|
* ÀÚµ¿ ÀçÁ¢¼Ó ¿©ºÎ(Ŭ¶óÀ̾ðÆ®)
|
*
|
* \returns
|
* Á¢¼Ó ¼º°ø : TRUE, ½ÇÆÐ : FALSE
|
*
|
* ÀçÁ¢¼Ó ¸ðµåÀÏ °æ¿ì ConnectThread¸¦ »ý¼ºÇÏ¿© ÁÖ±âÀûÀ¸·Î ÀçÁ¢¼ÓÀ» ½ÃµµÇϸç\n
|
* 1ȸ Á¢¼Ó ¸ðµåÀÏ °æ¿ì ConnectProcess ÇÔ¼ö¸¦ 1ȸ È£ÃâÇÑ´Ù.
|
*
|
*/
|
BOOL CIOCPController::Connect(BOOL bReconnect)
|
{
|
m_bReconnect = bReconnect;
|
if (!m_bReconnect)
|
return ConnectProcess();
|
else
|
{
|
DWORD dwThreadId;
|
HANDLE hConnect = CreateThread(NULL, 0, ConnectThread, this, 0, &dwThreadId);
|
CloseHandle(hConnect);
|
hConnect = NULL;
|
}
|
|
return TRUE;
|
}
|
|
/*!
|
* \brief
|
* Connect ÀÛ¾÷ ó¸®!!
|
*
|
*
|
* ¼¹ö·Î Á¢¼Ó ¿¬°á ¿äûÀ» ÇÏ´Â ÇÔ¼ö
|
*
|
|
*/
|
BOOL CIOCPController::ConnectProcess()
|
{
|
m_EventExitConnectThread = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
int ErrCode = 0;
|
|
char chCurIP[32] = {0, };
|
m_straCurIP = m_strIP;
|
|
sprintf_s(chCurIP, sizeof(chCurIP), m_straCurIP);
|
|
SOCKET clientsocket = INVALID_SOCKET;
|
int sockaddr_size = sizeof(SOCKADDR_IN);
|
SOCKADDR_IN clientsockaddr;
|
clientsockaddr.sin_family = AF_INET;
|
clientsockaddr.sin_port = htons(m_nPort);
|
clientsockaddr.sin_addr.S_un.S_addr = inet_addr(chCurIP);
|
|
//TRACE("IOCP::ConnectProcess() - Connecting Started \n");
|
|
int retval;
|
__try
|
{
|
do
|
{
|
Sleep(1);
|
/********************************************************************************/
|
// Server¿¡ Connect
|
/********************************************************************************/
|
retval = SOCKET_ERROR;
|
if (!m_bConnected)
|
{
|
if(clientsocket != INVALID_SOCKET)
|
closesocket(clientsocket);
|
clientsocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
|
if(clientsocket == INVALID_SOCKET)
|
{
|
//TRACE("IOCP::ConnectProcess() - SOCKET Create Failed \n");
|
return FALSE;
|
}
|
|
|
// ³íºí·°Å· Á¢¼Ó ½Ãµµ
|
u_long non_blk = TRUE;
|
if(SOCKET_ERROR == ioctlsocket(clientsocket, FIONBIO, &non_blk))
|
return TRUE;
|
|
timeval timevalue;
|
|
fd_set fdset;
|
FD_ZERO(&fdset);
|
FD_SET(clientsocket, &fdset);
|
|
timevalue.tv_sec = 2;
|
timevalue.tv_usec = 0;
|
|
|
retval = connect(clientsocket, (SOCKADDR *)&clientsockaddr, sizeof(clientsockaddr));
|
|
::select( (int)(clientsocket+1),NULL,&fdset,NULL,&timevalue);
|
if( FD_ISSET(clientsocket,&fdset) == FALSE)
|
{
|
//TRACE("[CIOCPController::ConnectProcess()] connect Timeout \n");
|
retval = SOCKET_ERROR;
|
}
|
else
|
{
|
retval = TRUE;
|
}
|
|
non_blk = FALSE;
|
if(SOCKET_ERROR == ioctlsocket(clientsocket, FIONBIO, &non_blk))
|
{
|
closesocket(clientsocket);
|
return FALSE;
|
}
|
|
|
if (retval == SOCKET_ERROR)
|
closesocket(clientsocket);
|
|
|
|
|
|
|
int n = WSAGetLastError();
|
//TRACE("[CIOCPController::ConnectProcess()] connect retrun[%d] LastError Code = [%d] \n",retval,n);
|
}
|
|
if (retval == SOCKET_ERROR)
|
{
|
if (m_bReconnect)
|
{
|
Sleep(500);
|
continue;
|
}
|
else
|
{
|
//TRACE("Connect Process Á¾·á ¼º°ø - Á¢¼ÓX, ÀçÁ¢¼ÓX!\n");
|
return FALSE;
|
}
|
}
|
|
EnterCriticalSection(&m_csContext);
|
m_bConnected = TRUE;
|
|
/********************************************************************************/
|
// ¼ÒÄÏ ÄÁÅØ½ºÆ® ÇÒ´ç -> Completion Key
|
// Per Socket Context ¸Þ¸ð¸® ÇÒ´ç
|
/********************************************************************************/
|
m_pSocketCtx = AllocPerSocketContext(clientsocket);
|
if(m_pSocketCtx == NULL)
|
{
|
//TRACE("IOCP::AcceptProcess() - Socket Context Allocation Error \n");
|
closesocket(clientsocket);
|
m_bConnected = FALSE;
|
LeaveCriticalSection(&m_csContext);
|
continue;
|
}
|
|
/********************************************************************************/
|
// IOCP Ä¿³Î °´Ã¼¿Í ¿¬°á
|
/********************************************************************************/
|
if(Associate(clientsocket, reinterpret_cast<ULONG_PTR>(m_pSocketCtx), &ErrCode) == FALSE)
|
{
|
//TRACE("IOCP::AcceptProcess() - Associating Error: %d \n", ErrCode);
|
LeaveCriticalSection(&m_csContext);
|
CloseSocket(m_pSocketCtx,FALSE,FALSE);
|
m_pSocketCtx = NULL;
|
continue;
|
}
|
|
/********************************************************************************/
|
// Ãʱâ Recv ¿äû
|
/********************************************************************************/
|
if(RecvPost(m_pSocketCtx) == FALSE)
|
{
|
//TRACE("IOCP::AcceptProcess() - Init RecvPost Error! \n ");
|
LeaveCriticalSection(&m_csContext);
|
CloseSocket(m_pSocketCtx,FALSE,FALSE);
|
m_pSocketCtx = NULL;
|
continue;
|
}
|
|
ConnectedSocket(m_pSocketCtx);
|
LeaveCriticalSection(&m_csContext);
|
|
|
} while (m_bReconnect);
|
}
|
__finally
|
{
|
if(AbnormalTermination() == TRUE)
|
{
|
// return À̳ª ¿¹¿Ü »óȲ¿¡¼ ÀÌÂÊÀ¸·Î µé¾î¿È.
|
|
//TRACE("IOCP::AcceptProcess() - Called CloseSocket() in __finally! \n");
|
if (m_pSocketCtx != NULL)
|
{
|
//LeaveCriticalSection(&m_csContext);
|
CloseSocket(m_pSocketCtx,FALSE,FALSE);
|
m_pSocketCtx = NULL;
|
}
|
SetEvent(m_EventExitConnectThread);
|
|
//return FALSE;
|
}
|
else
|
{
|
//TRACE("Connect Process Á¾·á ¼º°ø!\n");
|
SetEvent(m_EventExitConnectThread);
|
}
|
OutputDebugString(_T("Connection Thread Á¾·á Á÷Àü __finally ·çƾ ¿Ï·á\n"));
|
}
|
OutputDebugString(_T("Connection Thread Á¾·á\n"));
|
return TRUE; // jump out of __finally block has undefined behavior during termination handling
|
}
|
|
DWORD __stdcall CIOCPController::ConnectThread(PVOID pvParam)
|
{
|
CIOCPController* pCont = static_cast<CIOCPController*>(pvParam);
|
pCont->ConnectProcess();
|
|
return 0;
|
}
|
|
/********************************************************************************/
|
//
|
/********************************************************************************/
|
//************************************
|
// Method: ProcessingThread
|
// FullName: CIOCPController::ProcessingThread
|
// Access: private
|
// Returns: void
|
// Qualifier: CIOCPHandler::IocpWorkerThreadStartingPoint(PVOID pvParam) ¿¡¼ È£Ãâ
|
// Parameter: void
|
//************************************
|
|
|
/*!
|
* \brief
|
* Work Thread Function!!!!!
|
*
|
*
|
* IOCP ¸Þ½ÃÁö 󸮸¦ À§ÇÑ ¿öÄ¿ ¾²·¹µå·Î½á\n
|
* IOCP ¿¡ ¸Þ½ÃÁö°¡ ¹ß»ýÇÏ¸é ¾²·¹µå¸¦ ±ú¿ö¼ ¸Þ½ÃÁö¸¦ ó¸®ÇÑ´Ù.
|
*
|
*/
|
void CIOCPController::ProcessingThread(void)
|
{
|
pPerSocketContext pPerSocketCtx = NULL;
|
pPerIoContext pPerIoCtx = NULL;
|
DWORD dwBytesTransferred = 0;
|
int ErrCode = 0;
|
while (TRUE)
|
{
|
// IO Completion Packet ¾ò¾î¿Â´Ù.
|
BOOL bRet = GetCompletionStatus(reinterpret_cast<ULONG_PTR*>(&pPerSocketCtx), &dwBytesTransferred,
|
reinterpret_cast<LPOVERLAPPED*>(&pPerIoCtx), &ErrCode);
|
try
|
{
|
if(bRet)
|
{
|
if(((__int64)pPerSocketCtx) == THREAD_DIE)
|
{
|
//TRACE("Thread[%d] IOCP::ProcessingThread() - THREAD_DIE! \n",GetCurrentThreadId());
|
break;
|
}
|
}
|
|
if(m_nExit == TRUE)
|
{
|
//TRACE("ÀÌ¹Ì IOCP Controller Á¾·á µÊ. ¿öÄ¿¾²·¹µåµµ Á¾·á\n");
|
break;
|
}
|
|
if (dwBytesTransferred == 0)
|
{
|
//TRACE("Client Connection Closed\n");
|
throw "@@@ Client Connection Closed.";
|
}
|
|
////TRACE("Thread[%d] Process Retrun[%d], pPerSocketCtxp[%X], pPerIOCtx[%X], dwBytesTransferred[%d] \n",GetCurrentThreadId(), bRet,pPerSocketCtx,pPerIoCtx,dwBytesTransferred);
|
|
// ¿¡·¯ ó¸®.
|
if(bRet)
|
{
|
if(NULL == pPerIoCtx)
|
{
|
//TRACE("IOCP::ProcessingThread() - Getting Completion Packet Failed %d \n",ErrCode);
|
continue;
|
}
|
}
|
else
|
{
|
if(NULL != pPerIoCtx)
|
{
|
// ¿©±â·Î ¿À¸é ¿¡·¯°¡ 64ÀÏ °¡´É¼ºÀÌ ³ô´Ù.
|
// Áï ÁöÁ¤µÈ ³×Æ®¿öÅ© À̸§À» »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù. ÀÌ´Ù.
|
// ¹¹ ÀÌ·²¶© ¼ÒÄÏ ²÷¾î¹ö¸®¸é ¸¸»ç OKÀÌ´Ù.
|
CloseSocket(pPerSocketCtx);
|
//TRACE("@@@ IOCP::ProcessingThread() - CloseSocket() in pPerIoCtx != NULL\r\n");
|
|
|
}
|
continue;
|
}
|
|
|
// Ŭ¶óÀÌ¾ðÆ®°¡ ¿¬°á ²÷À½
|
if (dwBytesTransferred == 0)
|
{
|
//TRACE("Client Connection Closed\n");
|
throw "@@@ Client Connection Closed.";
|
}
|
|
// IO ¼º°Ý¿¡ µû¶ó ±×¿¡ µû¸¥ ó¸®
|
if (pPerIoCtx == pPerSocketCtx->recvContext)
|
{
|
// RECV Operation
|
//TRACE("-Thread[%d] recv IO Start\n",GetCurrentThreadId());
|
if (!RecvCompleteEvent(pPerSocketCtx, dwBytesTransferred))
|
{
|
throw "RecvCompleteEvent Error\n";
|
}
|
//TRACE("-Thread[%d] recv IO End\n",GetCurrentThreadId());
|
}
|
else if (pPerIoCtx == pPerSocketCtx->sendContext)
|
{
|
// SEND Operation
|
//TRACE("-Thread[%d] send IO Start\n",GetCurrentThreadId());
|
if(!SendCompleteEvent(pPerSocketCtx, dwBytesTransferred))
|
{
|
throw "SendCompleteEvent Error\n";
|
}
|
//TRACE("-Thread[%d] send IO End\n",GetCurrentThreadId());
|
}
|
else
|
{
|
//TRACE("-Thread[%d] Other IO Start\n",GetCurrentThreadId());
|
if(!OtherCompleteEvent(pPerSocketCtx, dwBytesTransferred))
|
{
|
throw "OtherCompleteEvent Error\n";
|
}
|
//TRACE("-Thread[%d] Other IO End\n",GetCurrentThreadId());
|
}
|
}
|
catch (char* errText)
|
{
|
//TRACE("IOCP::ProcessingThread() - Exception \'%s , Next CloseSocket Call\n", errText);
|
CloseSocket(pPerSocketCtx);
|
|
}
|
}
|
|
InterlockedDecrement(&m_nLiveThreadNum);
|
//TRACE("IOCP Worker Thread[%d] Exit ³²Àº ¾²·¹µå °³¼ö[%d]\n",GetCurrentThreadId(),m_nLiveThreadNum);
|
if(m_nLiveThreadNum <= 0)
|
{
|
SetEvent(m_EventExitWorkerThread);
|
}
|
}
|
|
/********************************************************************************/
|
// Recv ¿äû, Send ó¸®.
|
// return °ª: TRUE -> ¿¡·¯ ¾øÀÌ Á¤»óÀûÀ¸·Î 󸮵Ê
|
// FALSE -> ¿Ï·á ÆÐŶ ó¸® µ¿ÀÛ Áß ¿¡·¯ ¹ß»ý
|
// ¸®½Ãºê À̺¥Æ® ó¸® Çڵ鷯 ÇÔ¼ö
|
/********************************************************************************/
|
|
|
/*!
|
* \brief
|
* ¸®½Ãºê À̺¥Æ® ó¸® Çڵ鷯 ÇÔ¼ö
|
*
|
* \param pPerSocketCtx
|
* Recv ¼ÒÄÏ ÄÁÅØ½ºÆ®
|
*
|
* \param dwBytesTransferred
|
* ¹ÞÀº ¹ÙÀÌÆ® ¼ö
|
*
|
* \returns
|
* TRUE -> ¿¡·¯ ¾øÀÌ Á¤»óÀûÀ¸·Î 󸮵Ê\n
|
* FALSE -> ¿Ï·á ÆÐŶ ó¸® µ¿ÀÛ Áß ¿¡·¯ ¹ß»ý
|
|
*/
|
BOOL CIOCPController::RecvCompleteEvent(pPerSocketContext pPerSocketCtx, DWORD dwBytesTransferred)
|
{
|
BOOL bRet = TRUE;
|
WSABUF* pBuf = NULL;
|
pPerSocketCtx->recvContext->ResetBuffer();
|
|
int nCount = 0;
|
while(TRUE)
|
{
|
nCount++;
|
pBuf = pPerSocketCtx->recvContext->GetBuffer();
|
if (pBuf != NULL)
|
{
|
|
//TRACE("Thread[%d] Socket[%d] RecvCompleted - Start\n",GetCurrentThreadId(), pPerSocketCtx->socket);
|
bRet = RecvCompleted(pPerSocketCtx, dwBytesTransferred); // ´Ù ó¸®Çß´Ù°í °¡Á¤.
|
//TRACE("Thread[%d] Socket[%d] RecvCompleted[%d] - End\n",GetCurrentThreadId(),bRet, pPerSocketCtx->socket);
|
break;
|
}
|
|
if(nCount >= 1000)
|
{
|
//TRACE("[%d]¾Æ³ö¾¾¹ß..count[%d]\n",GetCurrentThreadId(),nCount);
|
}
|
Sleep(1);
|
}
|
|
|
if (bRet)
|
pPerSocketCtx->recvContext->ReleaseBuffer(); // Buffer ÃʱâÈ
|
else
|
pPerSocketCtx->recvContext->UnlockBuffer();
|
|
// ´Ù½Ã Recv ¿äûÀ» Çϰí WTQ·Î µé¾î°£´Ù.
|
return RecvPost(pPerSocketCtx);
|
}
|
|
/*!
|
* \brief
|
* Send ¿Ï·á ÆÐŶ ó¸® Çڵ鷯 ÇÔ¼ö
|
*
|
* \param pPerSocketCtx
|
* Send ¼ÒÄÏ ÄÁÅØ½ºÆ®
|
*
|
* \param dwBytesTransferred
|
* Àü¼ÛµÈ ¹ÙÀÌÆ® ¼ö
|
*
|
* \returns
|
* TRUE -> ¿¡·¯ ¾øÀÌ Á¤»óÀûÀ¸·Î 󸮵Ê\n
|
* FALSE -> ¿Ï·á ÆÐŶ ó¸® µ¿ÀÛ Áß ¿¡·¯ ¹ß»ý
|
|
*/
|
BOOL CIOCPController::SendCompleteEvent(pPerSocketContext pPerSocketCtx, DWORD dwBytesTransferred)
|
{
|
// Àü¼ÛµÈ Byte°¡ 0 º¸´Ù À۰ųª ÃÖ´ë ¹öÆÛº¸´Ù Å©¸é ¿À·ù
|
if (dwBytesTransferred < 0 || dwBytesTransferred > MAX_BUFFER_SIZE)
|
{
|
pPerSocketCtx->sendContext->ReleaseBuffer();
|
////TRACE("Error : SendCompleteEvent. Trans Size Mismatch %d", dwBytesTransferred);
|
return FALSE;
|
}
|
|
WSABUF* pBuf = pPerSocketCtx->sendContext->GetLockedBuffer();
|
if (dwBytesTransferred < static_cast<DWORD>(pPerSocketCtx->sendContext->GetLen()))
|
{
|
// ¸ðµÎ º¸³»ÁöÁö ¾Ê¾Ò±â ¶§¹®¿¡ ÀçÀü¼Û.
|
if (!pBuf)
|
{
|
//TRACE("Buffer Error : SendCompleteEvent \n");
|
return FALSE;
|
}
|
|
// //TRACE("SendPost Size Mismatch %d, Sent %d", pBuf->len, dwBytesTransferred);
|
pBuf->buf += dwBytesTransferred;
|
pBuf->len -= dwBytesTransferred;
|
SendPost(pPerSocketCtx);
|
}
|
else
|
{
|
SendCompleted(pPerSocketCtx, dwBytesTransferred);
|
pPerSocketCtx->sendContext->ReleaseBuffer();
|
}
|
|
return TRUE;
|
}
|
|
|
/*!
|
* \brief
|
* ¸Þ½ÃÁö ¼ö½Å ºÎ
|
*
|
* \param pPerSocketCtx
|
* ¼ö½ÅµÈ ÄÁÅØ½ºÆ®
|
*
|
* \returns
|
* ¼º°ø : TRUE, ½ÇÆÐ : FALSE
|
*
|
* \throws <exception class>
|
* return FALSE
|
*
|
* IOCP -> Work Thread -> Recv ¼ö½Å -> RecvPost
|
|
*
|
*/
|
BOOL CIOCPController::RecvPost(pPerSocketContext pPerSocketCtx)
|
{
|
DWORD dwRecvBytes = 0;
|
DWORD dwFlags = 0;
|
|
try
|
{
|
// ¼ö½Å.
|
WSABUF* pBuf = pPerSocketCtx->recvContext->GetLockedBuffer();
|
WSAOVERLAPPED* pOverlapped = pPerSocketCtx->recvContext->GetOverlapped();
|
if (!pBuf || !pOverlapped)
|
return FALSE;
|
|
// ÄÁÅØ½ºÆ®·ÎºÎÅÍ ¹öÆÛ¸¦ Àоî¿Â´Ù.
|
int ret = WSARecv(pPerSocketCtx->socket, pBuf, 1, &dwRecvBytes, &dwFlags, pOverlapped, NULL);
|
if(SOCKET_ERROR == ret)
|
{
|
int ErrCode = WSAGetLastError();
|
if(ErrCode != WSA_IO_PENDING && ErrCode != WSAEWOULDBLOCK)
|
{
|
//TRACE("IOCP::RecvPost() - WSARecv() Failed: %d, %d \n", ErrCode, pPerSocketCtx->recvContext->GetLen());
|
return FALSE;
|
}
|
}
|
}
|
catch(...)
|
{
|
//TRACE("IOCP::RecvPost() - Exception \n");
|
return FALSE;
|
}
|
|
return TRUE;
|
}
|
|
/*!
|
* \brief
|
* ¸Þ½ÃÁö ¼Û½Å ¿äû ºÎ
|
*
|
* \param pPerSocketCtx
|
* ¼Û½ÅÇÒ ÄÁÅØ½ºÆ®
|
*
|
* \returns
|
* ¼º°ø : TRUE, ½ÇÆÐ : FALSE
|
*
|
* \throws <exception class>
|
* return FALSE
|
*
|
* IOCP
|
*
|
*
|
*/
|
int CIOCPController::SendPost(pPerSocketContext pPerSocketCtx)
|
{
|
if (!pPerSocketCtx)
|
return 0;
|
|
int iSend;
|
DWORD dwSended;//, dwIOBytes, dwTotBytes;
|
|
try
|
{
|
// Size ÃʱâÈ.
|
WSABUF* pBuf = pPerSocketCtx->sendContext->GetLockedBuffer();
|
WSAOVERLAPPED* pOverlapped = pPerSocketCtx->sendContext->GetOverlapped();
|
if (!pBuf || !pOverlapped)
|
return 0;
|
|
pPerSocketCtx->sendContext->ResetOverlapped();
|
// Àü¼Û.
|
dwSended = 0;
|
iSend = WSASend(pPerSocketCtx->socket, pBuf, 1, &(dwSended), 0, pOverlapped, NULL);
|
if (SOCKET_ERROR == iSend) // ErrorÀÏ °æ¿ì´Â Break;
|
{
|
int nError = WSAGetLastError();
|
if (WSA_IO_PENDING == nError || WSAEWOULDBLOCK == nError)
|
{
|
// //TRACE("WSASend() Error : %d", nError);
|
}
|
else if (nError == WSAECONNRESET) // Á¢¼Ó Àç¼³Á¤(Á¾·á)
|
{
|
//TRACE("WSASend() - WSAECONNRESET \n");
|
CloseSocket(pPerSocketCtx);
|
}
|
else
|
{
|
//TRACE("WSASend() - Unknown Error : %d \n", nError);
|
return 1;
|
}
|
}
|
else
|
{
|
if (dwSended == 0) // º¸³½ Bytes ¼ö°¡ 0ÀÏ °æ¿ì Break;
|
return 2;
|
}
|
}
|
catch(...)
|
{
|
//TRACE("IOCP::SendPost() - Exception \n");
|
return 0;
|
}
|
|
return 1;
|
}
|
|
/*!
|
* \brief
|
* ¸Þ½ÃÁö ¼Û½Å ¿äû ºÎ
|
*
|
* \param pPerSocketCtx
|
* Description of parameter pPerSocketCtx.
|
*
|
* \param pBuffer
|
* ¼Û½ÅÇÒ ¹öÆÛ
|
*
|
* \param nLen
|
* ¹öÆÛÀÇ ±æÀÌ Á¤º¸
|
*
|
* \returns
|
* ¼º°ø : TRUE, ½ÇÆÐ : FALSE
|
*
|
* \throws <exception class>
|
* Description of criteria for throwing this exception.
|
*
|
* pBuffer ³»¿ëÀ» ¼ÒÄÏ¿¡ ´ã¾Æ¼ ¼Û½ÅÇÑ´Ù.
|
*
|
*/
|
int CIOCPController::SendPost(pPerSocketContext pPerSocketCtx, void* pBuffer, int nLen)
|
{
|
WSABUF* pBuf = pPerSocketCtx->sendContext->GetLockedBuffer();
|
if (!pBuf)
|
return 0;
|
|
if (nLen > MAX_BUFFER_SIZE)
|
return 0;
|
|
memcpy(pBuf->buf, pBuffer, nLen);
|
pBuf->len = nLen;
|
pPerSocketCtx->sendContext->UnlockBuffer();
|
return SendPost(pPerSocketCtx);
|
}
|
|
/*!
|
* \brief
|
* Recv, Send ¿Ï·á µ¿ÀÛ ¿ÜÀÇ Ã³¸® Çڵ鷯 ÇÔ¼ö
|
*
|
* \param pPerSocketCtx
|
* ¼ÒÄÏ ÄÁÅØ½ºÆ®
|
*
|
* \param dwBytesTransferred
|
* ¹ÞÀº ¹ÙÀÌÆ® ¼ö
|
*
|
* \returns
|
* FALSE
|
* \throws <exception class>
|
* Description of criteria for throwing this exception.
|
*
|
* ¿©±â·Î µé¾î¿À´Â À̺¥Æ®´Â Send, Recv ÀÌ¿ÜÀÇ ¸Þ½ÃÁö·Î ¼ÒÄÏÀ» ´Ý°í FALSE¸¦ ¹ÝȯÇÑ´Ù.
|
*
|
*/
|
BOOL CIOCPController::OtherCompleteEvent(pPerSocketContext pPerSocketCtx, DWORD dwBytesTransferred)
|
{
|
// ÇöÀç ¿©±â·Î ¿À¸é Recv , Send ÀÌ¿ÜÀÇ ÀÌ»óÇÑ µ¿ÀÛÀ» °¡¸®Å´ ¼ÒÄÏ ²÷¾î¹ö¸®ÀÚ.
|
CloseSocket(pPerSocketCtx);
|
|
return FALSE; // ¿¡·¯¸¦ °¡¶óÅ´
|
}
|
|
/********************************************************************************/
|
//
|
/********************************************************************************/
|
|
/*!
|
* \brief
|
* Ŭ¶óÀÌ¾ðÆ® ¼ÒÄÏ ÄÁÅØ½ºÆ® Á¦°ÅÇÏ°í ¼ÒÄÏ ´ÝÀ½
|
*
|
* \param pPerSocketCtx
|
* ´ÝÀ» ¼ÒÄÏ
|
*
|
* \param bGraceful
|
* TRUE : Á¤»ó ÇÁ·Î¼¼½º·Î ¼ÒÄÏ ÇØÁ¦ \n
|
* FALSE : °Á¦ ¼ÒÄÏ ÇØÁ¦
|
*
|
* \param bNotify
|
* TRUE : ¼ÒÄÏÀÌ ²÷¾îÁ³À»À½ Class¿¡ ÅëÁöÇÑ´Ù.
|
*
|
*/
|
void CIOCPController::CloseSocket(pPerSocketContext pPerSocketCtx, BOOL bGraceful, BOOL bNotify)
|
{
|
EnterCriticalSection(&m_csContext);
|
//TRACE("Call! CloseSocket \n");
|
|
if (!pPerSocketCtx)
|
{
|
|
if (m_NetMode == ClientMode && m_bConnected == TRUE)
|
{
|
m_bConnected = FALSE;
|
//TRACE("CloseSocket ÄÁÅØ½ºÆ®¾øÀ½ : Client Mode m_bConnected[%d] \n",m_bConnected);
|
}
|
LeaveCriticalSection(&m_csContext);
|
return;
|
}
|
|
try
|
{
|
|
//TRACE("CloseSocket ; %d, Socket %d, this %d\n", reinterpret_cast<int>(pPerSocketCtx), pPerSocketCtx->socket, reinterpret_cast<int>(this));
|
if(pPerSocketCtx != NULL)
|
{
|
if (m_NetMode == ClientMode && !m_bConnected)
|
{
|
LeaveCriticalSection(&m_csContext);
|
return;
|
}
|
|
if (pPerSocketCtx->socket != INVALID_SOCKET)
|
{
|
// SocketÀÌ ²÷¾îÁ³À½À» »ó¼ÓÇÏ´Â Class¿¡ ¾Ë·ÁÁØ´Ù.
|
//TRACE("-- Notify Call -- \n");
|
if (bNotify)
|
SocketClosed(pPerSocketCtx);
|
//TRACE("-- Notify End -- \n");
|
|
if(!bGraceful)
|
{
|
LINGER LingerStruct;
|
LingerStruct.l_onoff = 1;
|
LingerStruct.l_linger = 0; // closesocketÀº °ð¹Ù·Î ¸®ÅÏÇÏ°í ¼Û½Å ¹öÆÛÀÇ µ¥ÀÌÅÍ´Â »èÁ¦ÇÑ ÈÄ TCP ¿¬°áÀ» °Á¦ Á¾·áÇÑ´Ù.
|
setsockopt(pPerSocketCtx->socket, SOL_SOCKET, SO_LINGER, (char*)&LingerStruct, sizeof(LingerStruct));
|
}
|
|
// ¼ÒÄÏ ´Ý°í ¸Þ¸ð¸® ¹Ýȯ
|
//TRACE("´Ý°í ½ÍÀº ¼ÒÄÏ[%d] \n",pPerSocketCtx->socket);
|
int nRet = closesocket(pPerSocketCtx->socket);
|
if(nRet != 0)
|
{
|
//TRACE("closesocket retrun error %d Code[%d] \n",nRet,WSAGetLastError());
|
}
|
|
pPerSocketCtx->socket = INVALID_SOCKET;
|
|
DeallocPerSocketContext(pPerSocketCtx);
|
}
|
|
pPerSocketCtx = NULL;
|
|
if (m_NetMode == ClientMode)
|
{
|
m_bConnected = FALSE;
|
//TRACE("CloseSocket Client Mode m_bConnected[%d] \n",m_bConnected);
|
}
|
}
|
LeaveCriticalSection(&m_csContext);
|
}
|
catch(...)
|
{
|
//TRACE("CloseSocket Exception!!! \n");
|
LeaveCriticalSection(&m_csContext);
|
return;
|
}
|
}
|
|
/*!
|
* \brief
|
* IOCP ¼¹ö Á¤Áö
|
*
|
* IOCP ¼¹ö¸¦ Á¤ÁöÇÏ´Â ÇÔ¼ö·Î \n
|
* 1. ¸ðµç IOCP ¾²·¹µåÀÇ Á¤Áö(ÃÖ¿ì¼±)
|
* 2. ¼¹ö¸ðµå - Listen ¼ÒÄÏÀ» ÇØÁ¦
|
* 3. Ŭ¶óÀÌ¾ðÆ®¸ðµå - ConnectionThread°¡ »ì¾ÆÀÖÀ¸¸é Á¾·á ÈÄ ¼ÒÄÏ ÇØÁ¦
|
*
|
* \remarks
|
* IOCP ¿öÄ¿ ¾²·¹µå´Â ÃÖ¿ì¼±À¸·Î Á×ÀδÙ.
|
*
|
*/
|
void CIOCPController::DeinitNetwork()
|
{
|
//TRACE("--- IOCP::CIOCPController::DeinitNetwork() Start \n");
|
m_bReconnect = FALSE;
|
|
CloseAllThreads();
|
|
if (m_NetMode == ServerMode)
|
{
|
m_bConnected = FALSE;
|
closesocket(m_ListenSocket);
|
m_ListenSocket = INVALID_SOCKET;
|
}
|
else if(m_NetMode == ClientMode)
|
{
|
if(m_EventExitConnectThread != NULL)
|
WaitForSingleObject(m_EventExitConnectThread, INFINITE);
|
|
if (m_bConnected)
|
{
|
CloseSocket(m_pSocketCtx);
|
m_pSocketCtx = NULL;
|
}
|
|
m_bConnected = FALSE;
|
}
|
|
//TRACE("--- IOCP::CIOCPController::DeinitNetwork() End \n");
|
}
|
|
//////////////////////////////////////////////////////////////
|
// ¿¡·¯¸Þ½ÃÁö, µð¹ö±ë
|
// µð¹ö±× Ãâ·Â
|
void CIOCPController::NoticeMsg(char *str, ...)
|
{
|
|
}
|