#include "Global.h" #include "NFConnection.h" #include namespace NaveServer { NFConnection::NFConnection() : m_nMaxBuf(0), m_nMaxPacketSize(0), m_sckListener(NULL), m_Socket(NULL), m_eConnectFlag(CONNECT_NONE), m_bIsConnect(FALSE), m_bForce(FALSE), m_hIOCP(NULL), m_pPacketPool(NULL), m_uRecvTickCnt(0) { m_RecvPacket.Init(); m_RecvIO.NewIOBuf(0); // 0À¸·Î ÇÏ¸é ±âº»ÀûÀ¸·Î 1024*64¸¸Å­ ÀâÈù´Ù. } NFConnection::~NFConnection() { m_nMaxBuf = m_nMaxPacketSize = 0; m_sckListener = NULL; Disconnect(); m_eConnectFlag = CONNECT_NONE; m_bIsConnect = FALSE; m_bForce = FALSE; m_hIOCP = NULL; m_pPacketPool = NULL; m_uRecvTickCnt = 0; m_RecvIO.DeleteIOBuf(); } BOOL NFConnection::Create( DWORD dwIndex, HANDLE hIOCP, SOCKET listener, NFPacketPool* pPacketPool, INT nMaxBuf) { // °´Ã¼ÀÇ ¸â¹ö º¯¼ö ¼³Á¤ m_dwIndex = dwIndex; m_hIOCP = hIOCP; m_sckListener = listener; m_pPacketPool = pPacketPool; m_nMaxBuf = m_nMaxPacketSize = nMaxBuf; // °´Ã¼ OPEN if(!Open()) { // ½ÇÆÐÇÏ¸é ¾î¶»°Ô ÇØ¾ß Çϴ°¡? ÀÌ ÄÁ³Ø¼Ç Ŭ·¡½º´Â Á×Àº Ŭ·¡½º°¡ µÈ´Ù. Close_Open(FALSE); return FALSE; } return TRUE; } BOOL NFConnection::Open() { // Àý´ë °ª ÀÖ¾î¾ß ÇÔ. assert(m_nMaxBuf); assert(m_nMaxPacketSize); // ÆÐŶ PoolÀÌ Á¦´ë·Î ¼³Á¤ µÇ¾ú´ÂÁö °Ë»ç if( !m_pPacketPool ) return FALSE; // Listener Socket »óÅ °Ë»ç if( m_sckListener == NULL ) return FALSE; m_RecvIO.InitIOBuf(); // ÆÐŶ¹öÆÛ¸¦ ÃʱâÈ­ÇÑ´Ù. // create socket for send/recv m_Socket = WSASocket( AF_INET, SOCK_STREAM, IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED ); // ÇöÀç ¼ÒÄÏÀÌ Á¦´ë·Î »ý¼º µÇ¾ú´ÂÁö °Ë»ç if(m_Socket == NULL) return FALSE; // AccpetÇÒ ¿À¹ö·¦±¸Á¶Ã¼¿Í ÆÐŶ¹öÆÛ¸¦ ÁغñÇÑ´Ù. LPOVERLAPPEDPLUS newolp = PrepareAcptPacket(); if(NULL == newolp) { closesocket(m_Socket); m_Socket = NULL; return FALSE; } ///////////////////////////////////////////////////////////////////// // Socket°ú Listener¿Í ¿¬°á // Overlapped¿¡ µé¾î°¡´Â º¯¼ö°¡ ³ªÁß¿¡ IOCP À̺¥Æ® ¹ß»ý 󸮿¡ ¾²Àδ٠BOOL bRet = AcceptEx(newolp->sckListen, // Listen Socket newolp->sckClient, // Socket &(newolp->wbuf.buf[0]), // ¹öÆÛ Æ÷ÀÎÅÍ m_nMaxBuf, // ¹öÆÛ »çÀÌÁî sizeof(sockaddr_in) + 16, // ¼ÒÄÏ Á¤º¸ - IP, Address, Name.. etc sizeof(sockaddr_in) + 16, // ¼ÒÄÏ Á¤º¸ - IP, Address, Name.. etc &newolp->dwBytes, // ó¸® ¹ÙÀÌÆ® Å©±â &newolp->overlapped); // *Áß¿ä* // ¿¡·¯ ó¸® if(!bRet && WSAGetLastError() != WSA_IO_PENDING) { ShowMessage(ACCEPT_FAILED); closesocket(m_Socket); m_Socket = NULL; ReleaseAcptPacket(newolp); return FALSE; } ///////////////////////////////// // ¼ÒÄÏÀÇ ¼º´É ÃÖÀûÈ­¸¦ À§ÇÑ ¼¼ÆÃ INT zero = 0; INT err = 0; // Send Buffer¿¡ ´ëÇÑ ¼¼ÆÃ if( (err = setsockopt( m_Socket, SOL_SOCKET, SO_SNDBUF, (CHAR *)&zero, sizeof(zero))) == SOCKET_ERROR) { ShowMessage(ACCEPT_FAILED); closesocket(m_Socket); m_Socket = NULL; ReleaseAcptPacket(newolp); return FALSE; } // Receive Buffer¿¡ ´ëÇÑ ¼¼ÆÃ if((err = setsockopt( m_Socket, SOL_SOCKET, SO_RCVBUF, (CHAR *)&zero, sizeof(zero) )) == SOCKET_ERROR) { ShowMessage(ACCEPT_FAILED); closesocket(m_Socket); m_Socket = NULL; ReleaseAcptPacket(newolp); return FALSE; } // º¯¼ö ÃʱâÈ­ InterlockedExchange((LONG*)&m_bIsConnect,0); Clear(); m_uRecvTickCnt = 0 ; return TRUE; } BOOL NFConnection::Close_Open( BOOL bForce ) { // ¼ÒÄϰú ¸®½º³Ê »óÅ ȮÀÎ // Disconnect ÇÔ¼ö¾È¿¡¼­ OnDisconnect(), Clear() ÀÌ È£ÃâµÈ´Ù. Disconnect(bForce); // ÀÌ ÆÐŶ ´Ù½Ã ÃʱâÈ­ if(!Open()) { // ½ÇÆÐÇÏ¸é ¾î¶»°Ô ÇØ¾ß Çϴ°¡? ÀÌ ÄÁ³Ø¼Ç Ŭ·¡½º´Â Á×Àº Ŭ·¡½º°¡ µÈ´Ù. // ¹º°¡ Á×Àº »óŸ¦ Ç¥½ÃÇØÁÖ°í üũÇÏÀÚ. ±×¸®°í ³ªÁß¿¡ ŸÀ̸ӿ¡¼­ ´Ù½Ã ÃʱâÈ­ ÇØº»´Ù. ShowMessage(DEAD_CONNECTION); Disconnect(); return FALSE; } return TRUE; // Á¤»ó ó¸® } VOID NFConnection::ShowMessage(INT MsgIndex) { switch(MsgIndex) { case ACCEPT_FAILED: LOG_ERROR((L"[%04d] AcceptEx(): SOCKET_ERROR, %d.", GetIndex(), WSAGetLastError())); break; case CLOSE_SOCKET: LOG_INFO((L"[%04d] Á¢¼Ó ÇØÁ¦.", GetIndex())); break; case DEAD_CONNECTION: LOG_ERROR((L"[%04d] Dead Connection.", GetIndex())); break; case CONNECT_SUCCESS: LOG_INFO((L"[%04d] Á¢¼Ó ¼º°ø.", GetIndex())); break; case CONNECT_FAILED: LOG_ERROR((L"[%04d] Á¢¼Ó ½ÇÆÐ (Check Sum ¿À·ù).", GetIndex())); break; case DISPATCH_FAILED: LOG_ERROR((L"[%04d] Dispatch return FALSE.", GetIndex())); break; case DOIOSWITCH_FAILED: LOG_ERROR((L"[%04d] DoIo(..) - Switch Default.", GetIndex())); break; case ALLOCACPT_FAILED: LOG_ERROR((L"[%04d] PrepareAcptPacket() acpt packet alloc failed.", GetIndex())); break; case PREPAREACPT_FAILED: LOG_ERROR((L"[%04d] PrepareAcptPacket().newolp == NULL.", GetIndex())); break; case PREPARERECVSIZE_FAILED: LOG_ERROR((L"[%04d] PrepareRecvPacket() srclen > m_nMaxPacketSize.", GetIndex())); break; case PREPARESENDSIZE_FAILED: LOG_ERROR((L"[%04d] PrepareSendPacket() srclen > m_nMaxPacketSize.", GetIndex())); break; case ALLOCRECV_FAILED: LOG_ERROR((L"[%04d] PrepareRecvPacket() recv packet alloc failed.", GetIndex())); break; case ALLOCSEND_FAILED: LOG_ERROR((L"[%04d] PrepareSendPacket() send packet alloc failed.", GetIndex())); break; case PREPARERECV_FAILED: LOG_ERROR((L"[%04d] PrepareRecvPacket().newolp == NULL.", GetIndex())); break; case PREPARESEND_FAILED: LOG_ERROR((L"[%04d] PrepareSendPacket().newolp == NULL.", GetIndex())); break; case RELEASEACPT_FAILED: LOG_ERROR((L"[%04d] ReleaseAcptPacket() free acpt packet failed.", GetIndex())); break; case RELEASERECV_FAILED: LOG_ERROR((L"[%04d] ReleaseRecvPacket() free recv packet failed.", GetIndex())); break; case RELEASESEND_FAILED: LOG_ERROR((L"[%04d] ReleaseSendPacket() free send packet failed.", GetIndex())); break; case BINDIOCP_FAILED: LOG_ERROR((L"[%04d] BindIOCP().lpOverlapPlus == NULL.", GetIndex())); break; case RECVPOST_FAILED: LOG_ERROR((L"[%04d] RecvPost() m_Socket == NULL or IsConnect() == FALSE.", GetIndex())); break; case RECVPOSTPENDING_FAILED: LOG_ERROR((L"[%04d] RecvPost().WSARecv() == SOCKET_ERROR, %d.", GetIndex(), WSAGetLastError())); break; // case ALLOCPROC_FAILED: // LOG_ERROR((L"[%04d] SendPost().AllocProcBuffer == NULL or SOCKET_ERROR, %d.", GetIndex(), WSAGetLastError())); // break; case SENDPOSTPENDING_FAILED: LOG_ERROR((L"[%04d] SendPost().WSASend() == SOCKET_ERROR, %d.", GetIndex(), WSAGetLastError())); break; case SENDPOST_FAILED: LOG_ERROR((L"[%04d] SendPost() == SOCKET_ERROR, %d.", GetIndex(), WSAGetLastError())); break; } } BOOL NFConnection::DoIo( LPOVERLAPPEDPLUS lpOverlapPlus ) { // ÇÒ´ç ÆÐŶÀÇ »óÅ ȮÀÎ switch(lpOverlapPlus->nConnState) { // ACCEPT°ü·Ã ó¸® case ClientIoAccept: BindIOCP(lpOverlapPlus); // ÇöÀç ¼ÒÄϰú IOCP ¹ÙÀεù ó¸® InterlockedIncrement((LONG*)&m_bIsConnect); // Á¢¼Ó »óÅ º¯¼ö ON !!! // °Ë»çµÈ ¿¬°áÀÚ ¾Æ³­ °æ¿ì ¿¬°á ÇØÁ¦ if(lpOverlapPlus->dwBytes && strncmp(lpOverlapPlus->wbuf.buf,CONNECT_CHECK_DATA,CONNECT_CHECK_SIZE) == 0) { ShowMessage(CONNECT_SUCCESS); SetConnectFlag(CONNECT_TRUE); } else { ShowMessage(CONNECT_FAILED); LOG_ERROR((L"[%04d] Check Sum : %d, %s.", GetIndex(), lpOverlapPlus->dwBytes, lpOverlapPlus->wbuf.buf)); SetConnectFlag(CONNECT_FALSE); ReleaseAcptPacket( lpOverlapPlus ); break; } // Accept ÇÒ´ç ÆÐŶ ÇØÁ¦ if(!RecvPost()) { SetClose_Open(lpOverlapPlus); break; } // TICK Ä«¿îÆ® ¼³Á¤ InterlockedExchange((LONG*)&m_uRecvTickCnt,timeGetTime()); ReleaseAcptPacket( lpOverlapPlus ); break; // RECEIVE °ü·Ã ó¸® case ClientIoRead: // TICK Ä«¿îÆ® ¼³Á¤ InterlockedExchange((LONG*)&m_uRecvTickCnt,timeGetTime()); // ó¸® µ¥ÀÌŸ°¡ ¾ø´Ù¸é if(lpOverlapPlus->dwBytes == 0) { SetClose_Open(lpOverlapPlus, FALSE); // ¿¡·¯, °´Ã¼ ´Ù½Ã ÃʱâÈ­ } else if((INT)lpOverlapPlus->dwBytes == SOCKET_ERROR) // ¿¡·¯¶ó¸é { SetClose_Open(lpOverlapPlus, TRUE); // ¿¡·¯, °´Ã¼ ´Ù½Ã ÃʱâÈ­ } else// Á¤»óÀ̶ó¸é { // ¸Þ¼¼Áö ÀúÀå if(!DispatchPacket(lpOverlapPlus)) { ShowMessage(DISPATCH_FAILED); SetClose_Open( lpOverlapPlus, TRUE ); } else { // Receive ÇÒ´ç ÆÐŶ ÇØÁ¦ ReleaseRecvPacket( lpOverlapPlus ); } } break; case ClientIoWrite: ReleaseSendPacket( lpOverlapPlus ); break; default: ShowMessage(DOIOSWITCH_FAILED); assert(0); break; } return TRUE; } LPOVERLAPPEDPLUS NFConnection::PrepareAcptPacket() { LPOVERLAPPEDPLUS newolp = NULL; // get accept overlapped structure and packet buffer. if(m_pPacketPool->AllocAcptPacket(newolp) == FALSE) { ShowMessage(ALLOCACPT_FAILED); return NULL; } // Ä¡¸íÀûÀÎ ¿¡·¯ if(!newolp) { ShowMessage(PREPAREACPT_FAILED); return NULL; } // clear buffer memset(&newolp->overlapped , NULL, sizeof(OVERLAPPED)); memset(&newolp->wbuf.buf[0], NULL, sizeof(m_nMaxPacketSize)); // init olp structure newolp->sckListen = m_sckListener; newolp->sckClient = m_Socket; newolp->nConnState = ClientIoAccept; newolp->pClientConn = (PVOID)this; newolp->wbuf.len = CONNECT_CHECK_SIZE; // newolp->wbuf.len = MAXPACKETSIZE; // ** WARNING ** // When you change your packet certfying correct connection, // you must change the size of definition 'CONNECT_CHECK_SIZE'. return newolp; } LPOVERLAPPEDPLUS NFConnection::PrepareRecvPacket(UINT srclen) { // Ä¡¸íÀûÀÎ ¿¡·¯ if(srclen > (UINT)m_nMaxPacketSize) { ShowMessage(PREPARERECVSIZE_FAILED); return NULL; } LPOVERLAPPEDPLUS newolp = NULL; // get recv overlapped structure and packet buffer. if( FALSE == m_pPacketPool->AllocRecvPacket(newolp) ) { ShowMessage(ALLOCRECV_FAILED); return NULL; } // Ä¡¸íÀûÀÎ ¿¡·¯ if(!newolp) { ShowMessage(PREPARERECV_FAILED); return NULL; } // clear buffer memset(&newolp->overlapped , NULL, sizeof(OVERLAPPED)); memset(&newolp->wbuf.buf[0], NULL, sizeof(m_nMaxPacketSize)); // init olp structure newolp->sckListen = m_sckListener; newolp->sckClient = m_Socket; newolp->nConnState = ClientIoRead; newolp->pClientConn = (PVOID) this; if(srclen == 0) newolp->wbuf.len = m_nMaxPacketSize; else newolp->wbuf.len = srclen; return newolp; } LPOVERLAPPEDPLUS NFConnection::PrepareSendPacket(CHAR *psrcbuf, UINT srclen) { // Ä¡¸íÀûÀÎ ¿¡·¯ if(srclen < 0 || srclen > (UINT)m_nMaxPacketSize) { ShowMessage(PREPARESENDSIZE_FAILED); return NULL; } LPOVERLAPPEDPLUS newolp = NULL; // get recv overlapped structure and packet buffer. if( FALSE == m_pPacketPool->AllocSendPacket(newolp) ) { ShowMessage(ALLOCSEND_FAILED); return NULL; } // Ä¡¸íÀûÀÎ ¿¡·¯ if(!newolp) { ShowMessage(PREPARESEND_FAILED); return NULL; } // clear buffer memset(&newolp->overlapped , NULL, sizeof(OVERLAPPED)); memset(&newolp->wbuf.buf[0], NULL, sizeof(m_nMaxPacketSize)); // init olp structure newolp->sckListen = m_sckListener; newolp->sckClient = m_Socket; newolp->nConnState = ClientIoWrite; newolp->pClientConn = (PVOID) this; newolp->wbuf.len = srclen; memcpy(newolp->wbuf.buf,psrcbuf,srclen); return newolp; } BOOL NFConnection::ReleaseAcptPacket(LPOVERLAPPEDPLUS olp) { if(NULL == olp) return FALSE; if(NULL == olp->wbuf.buf) return FALSE; if(!m_pPacketPool->FreeAcptPacket(olp)) { ShowMessage(RELEASEACPT_FAILED); return FALSE; } return TRUE; } BOOL NFConnection::ReleaseRecvPacket(LPOVERLAPPEDPLUS olp) { if(olp == NULL) return FALSE; if(olp->wbuf.buf == NULL) return FALSE; if(!m_pPacketPool->FreeRecvPacket(olp)) { ShowMessage(RELEASERECV_FAILED); return FALSE; } return TRUE; } BOOL NFConnection::ReleaseSendPacket(LPOVERLAPPEDPLUS olp) { if(olp == NULL) return FALSE; if(olp->wbuf.buf == NULL) return FALSE; if(!m_pPacketPool->FreeSendPacket(olp)) { ShowMessage(RELEASESEND_FAILED); return FALSE; } return TRUE; } BOOL NFConnection::BindIOCP(LPOVERLAPPEDPLUS lpOverlapPlus) { // Ä¡¸íÀûÀÎ ¿¡·¯ if(!lpOverlapPlus) { ShowMessage(BINDIOCP_FAILED); return FALSE; } INT locallen, remotelen; sockaddr_in * plocal = 0, * premote = 0; GetAcceptExSockaddrs( &(lpOverlapPlus->wbuf.buf[0]), m_nMaxBuf, sizeof(sockaddr_in) + 16, sizeof(sockaddr_in) + 16, (sockaddr **)&plocal, // ¼­¹ö´Ü &locallen, (sockaddr **)&premote, // ·ÎÄÃ´Ü &remotelen ); memcpy(&m_Local, plocal, sizeof(sockaddr_in)); memcpy(&m_Peer, premote, sizeof(sockaddr_in)); if(CreateIoCompletionPort((HANDLE)lpOverlapPlus->sckClient,m_hIOCP,0,0) == 0) return FALSE; return TRUE; } void NFConnection::SetClose_Open(LPOVERLAPPEDPLUS lpOverlapPlus, BOOL bForce) { if(m_eConnectFlag != CONNECT_NONE) { LOG_ERROR((L"NFConnection::SetClose_Open() m_eConnectFlag == %d", (int)m_eConnectFlag)); } // ÇÒ´ç ÆÐŶ »óÅ °Ë»çÈÄ ÆÐŶ ÇÒ´ç ÇØÁ¦ if(NULL != lpOverlapPlus) { if(NULL != lpOverlapPlus->wbuf.buf && NULL != m_pPacketPool) { // ¸¶Áö¸·À¸·Î ¿Ï·á µÇ¾ú´ø ¿À¹ö·¦±¸Á¶Ã¼¿Í ¹öÆÛ¸¦ ¸±¸®ÁîÇÑ´Ù. switch( lpOverlapPlus->nConnState) { case ClientIoAccept: ReleaseAcptPacket( lpOverlapPlus ); break; case ClientIoRead: ReleaseRecvPacket( lpOverlapPlus ); break; case ClientIoWrite: ReleaseSendPacket( lpOverlapPlus ); break; default: break; } } } m_bForce = bForce; InterlockedExchange((LONG*)&m_eConnectFlag,CLOSEOPEN_TRUE); NFUpdateManager::GetInstance().Add(this, NULL); } void NFConnection::SetConnectFlag(CONNECT_EVENT eState) { if(m_eConnectFlag != CONNECT_NONE) { LOG_ERROR((L"NFConnection::SetConnectFlag() m_eConnectFlag == %s", (int)m_eConnectFlag)); } InterlockedExchange((LONG*)&m_eConnectFlag,eState); NFUpdateManager::GetInstance().Add(this, NULL); } BOOL NFConnection::DispatchPacket(LPOVERLAPPEDPLUS lpOverlapPlus) { // Read°°Àº°æ¿ì RecvPost ÇÒ¶§ ¸¶´Ù 1¹ø ¹ß»ýÇϴµ¥ ÇöÀç // ReadÇÒ¶§ RecvPost¸¦ 1¹ø¸¸ Çϱ⠴빮¿¡ ½º·¹µå°¡ ¾Æ¹«¸® ¸¹¾Æµµ.DispatchPacketÀº 1¹ø¸¸ ÀϾ´Ù. CHAR* psrcbuf = &( lpOverlapPlus->wbuf.buf[0] ); INT srclen = lpOverlapPlus->dwBytes; // PacketÁ¤º¸ ÀÚü°¡ [H 2byte][P size] Çü½ÄÀÌ´Ù. m_RecvIO.Append(psrcbuf, srclen); m_RecvIO.Lock(); // IOCP´Â ½º·¹µå ÆÐŶ󸮿¡ ÀÇÇÑ ¼º´ÉÇâ»óÀÌ ÁÖ ´É·ÂÀÌ´Ù // ±×·±µ¥ ¾Æ·¡¿Í °°ÀÌ UpdateManaget¿¡ ÆÐŶÀ» ³ÖÀºÈÄ ÁÖ ½º·¹µå¿¡¼­ Update¸¦ ó¸®Çϸé // µ¥µå¶ô°°Àº ¹®Á¦´Â »ý±âÁö ¾ÊÁö¸¸ ´ÙÁß󸮿¡ ÀÇÇÑ ¼º´ÉÇâ»óÀÌ »ý±âÁö ¾Ê´Â´Ù. // ÆÐŶÀº ½º·¹µå »óÅ¿¡¼­ ¹Ù·Î ó¸®ÇÏ°Ô ¼öÁ¤Çϰí UpdateManagerÀº Ä¿³ØÆ® Ç÷¡½º¸¦ // ¾÷µ¥ÀÌÆ® Çϴ°ɷΠÁ¦ÇÑÇØº¸ÀÚ. #ifdef ENABLE_UPDATEQUE if(m_RecvIO.GetPacket(&m_RecvPacket) == 1) { m_RecvPacket.DecryptPacket(); if(m_RecvPacket.IsAliveChecksum()) NFUpdateManager::GetInstance().Add(this, &m_RecvPacket); m_RecvPacket.Init(); } else m_RecvIO.UnLock(); #else // ¾Æ·¡¿Í °°ÀÌ ½º·¹µå¿¡¼­ ÆÐŶÀ» ó¸®ÇÏ°Ô µÇ¸é // Dispatch¿¡ Å©¸®Æ¼Äà ¼¼¼ÇÀ» Áý¾î³Ö¾î µ¥µå¶ô¿¡ ÁÖÀÇÇØ¾ßÇÑ´Ù. if(m_RecvIO.GetPacket(&m_RecvPacket) == 1) { m_RecvPacket.DecryptPacket(); if(m_RecvPacket.IsAliveChecksum()) { DispatchPacket(m_RecvPacket); } m_RecvPacket.Init(); } else m_RecvIO.UnLock(); #endif // ±×¸®°í »õ·Î¿î recieve buffer¸¦ ÁغñÇÏ¿© PostÇÑ´Ù. return RecvPost(); } VOID NFConnection::UpdatePacket(NaveNet::NFPacket& Packet) { if(Packet.GetCommand() != 0) { DispatchPacket(Packet); return; } // Ä¿³Ø¼ÇÀÇ »óŸ¦ ¾÷µ¥ÀÌÆ® ÇϱâÀ§ÇÑ ºÎºÐ. if(m_eConnectFlag == CONNECT_NONE) return; if(m_eConnectFlag == CONNECT_TRUE) { InterlockedExchange((LONG*)&m_eConnectFlag,CONNECT_NONE); OnConnect(TRUE); } else if(m_eConnectFlag == CONNECT_FALSE) { InterlockedExchange((LONG*)&m_eConnectFlag,CONNECT_NONE); OnConnect(FALSE); Close_Open(); } else if(m_eConnectFlag == DISCONNECT_TURE) { InterlockedExchange((LONG*)&m_eConnectFlag,CONNECT_NONE); Disconnect(FALSE); } else if(m_eConnectFlag == CLOSEOPEN_TRUE) { InterlockedExchange((LONG*)&m_eConnectFlag,CONNECT_NONE); Close_Open(m_bForce); } } BOOL NFConnection::SendPost( CHAR* pPackte, INT Len ) { if(!m_Socket) return FALSE; if(!IsConnect()) return FALSE; if(m_Socket == NULL || IsConnect() == FALSE) { ShowMessage(SENDPOST_FAILED); return FALSE; } // prepare recieve buffer LPOVERLAPPEDPLUS newolp = PrepareSendPacket(pPackte,Len); // Á¦´ë·Î ÇÒ´ç ¹Þ¾Ò´ÂÁö Á¶»ç if(newolp == NULL) return FALSE; INT ret = WSASend( newolp->sckClient, &newolp->wbuf, 1, &newolp->dwBytes, // ¸¸¾à È£ÃâÇßÀ»¶§ ¹Ù·Î ¹Þ¾Ò´Ù¸é ¿©±â·Î ¹ÞÀº Å©±â°¡ ³Ñ¾î¿ÀÁö¸¸ iocp¿¡¼­´Â Àǹ̰¡ ¾ø´Ù. newolp->dwFlags, &newolp->overlapped, // Overlapped ±¸Á¶Ã¼ NULL ); // ¿¡·¯ ó¸® if(ret == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING) { ShowMessage(SENDPOSTPENDING_FAILED); ReleaseSendPacket(newolp); return FALSE; } return TRUE; } BOOL NFConnection::SendPost( NaveNet::NFPacket& Packet ) // ½ÇÁ¦ Send ó¸® { // º¸³»±â Á÷Àü üũ¼¶À» »ý¼ºÇÑ´Ù. Packet.EncryptPacket(); INT Len = Packet.m_Header.Size; CHAR* pPacket = (CHAR*)&Packet; return SendPost(pPacket, Len); } BOOL NFConnection::RecvPost(UINT buflen) { if(m_Socket == NULL || IsConnect() == FALSE) { ShowMessage(RECVPOST_FAILED); return FALSE; } // prepare recieve buffer LPOVERLAPPEDPLUS newolp = PrepareRecvPacket(buflen); // Á¦´ë·Î ÇÒ´ç ¹Þ¾Ò´ÂÁö Á¶»ç if(newolp == NULL) return FALSE; INT ret = WSARecv( newolp->sckClient, &newolp->wbuf, 1, &newolp->dwBytes, // ¸¸¾à È£ÃâÇßÀ»¶§ ¹Ù·Î ¹Þ¾Ò´Ù¸é ¿©±â·Î ¹ÞÀº Å©±â°¡ ³Ñ¾î¿ÀÁö¸¸ iocp¿¡¼­´Â Àǹ̰¡ ¾ø´Ù. &newolp->dwFlags, &newolp->overlapped, // Overlapped ±¸Á¶Ã¼ NULL ); // ¿¡·¯ ó¸® if(ret == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING) { ShowMessage(RECVPOSTPENDING_FAILED); ReleaseRecvPacket(newolp); return FALSE; } return TRUE; } BOOL NFConnection::GetClientIP(INT *iIP) { if(iIP == NULL) return FALSE; if(!IsConnect()) { iIP[0] = 0; return FALSE; } iIP[0] = m_Peer.sin_addr.S_un.S_un_b.s_b1; iIP[1] = m_Peer.sin_addr.S_un.S_un_b.s_b2; iIP[2] = m_Peer.sin_addr.S_un.S_un_b.s_b3; iIP[3] = m_Peer.sin_addr.S_un.S_un_b.s_b4; return TRUE; } BOOL NFConnection::GetClientIP(CHAR *szIP) { if(szIP == NULL) return FALSE; if(!IsConnect()) { szIP[0] = NULL; return FALSE; } sprintf(szIP,"%d.%d.%d.%d",(INT)m_Peer.sin_addr.S_un.S_un_b.s_b1, (INT)m_Peer.sin_addr.S_un.S_un_b.s_b2, (INT)m_Peer.sin_addr.S_un.S_un_b.s_b3, (INT)m_Peer.sin_addr.S_un.S_un_b.s_b4); return TRUE; } BOOL NFConnection::GetClientIP(WCHAR *szIP) { if(szIP == NULL) return FALSE; if(!IsConnect()) { szIP[0] = NULL; return FALSE; } swprintf(szIP, L"%d.%d.%d.%d",(INT)m_Peer.sin_addr.S_un.S_un_b.s_b1, (INT)m_Peer.sin_addr.S_un.S_un_b.s_b2, (INT)m_Peer.sin_addr.S_un.S_un_b.s_b3, (INT)m_Peer.sin_addr.S_un.S_un_b.s_b4); return TRUE; } BOOL NFConnection::GetClientIP(sockaddr_in& addr) { if(!IsConnect()) { memcpy(&addr,0,sizeof(sockaddr_in)); return FALSE; } CopyMemory((CHAR*)&addr,(CHAR*)&m_Peer,sizeof(sockaddr_in)); return TRUE; } VOID NFConnection::Disconnect(BOOL bForce) { // ¿¬°á µÇ¾îÀÖ´ÂÁö È®ÀÎ if(!IsConnect()) return; // º¯¼ö ÃʱâÈ­ InterlockedExchange((LONG*)&m_eConnectFlag,CONNECT_NONE); InterlockedExchange((LONG*)&m_bIsConnect,FALSE); m_uRecvTickCnt = 0; m_bForce = FALSE; // ¼ÒÄϰú ¸®½º³Ê »óÅ ȮÀÎ if(m_Socket) { struct linger li = {0, 0}; // Default: SO_DONTLINGER shutdown(m_Socket, SD_BOTH ); // ¼ÒÄÏ¿¡ ó¸® µÇÁö ¾ÊÀº µ¥ÀÌŸ°¡ ¼ÒÄÏ ¹öÆÛ¿¡ ³²¾ÆÀÖ´Ù¸é, if(bForce) li.l_onoff = 1; // SO_LINGER, timeout = 0 // ÀÜ¿© µ¥ÀÌŸ°¡ ÀÖÀ¸¸é Á¦°Å setsockopt(m_Socket, SOL_SOCKET, SO_LINGER, (CHAR *)&li, sizeof(li)); closesocket(m_Socket); // ¼ÒÄÏ ´Ý±â m_Socket = NULL; // ÃʱâÈ­ ShowMessage(CLOSE_SOCKET); } OnDisconnect(); Clear(); } BOOL NFConnection::IsConnect() { BOOL bRet = m_bIsConnect; return bRet; } LONG NFConnection::GetRecvTickCnt() { LONG lRecvTickCount = m_uRecvTickCnt; return lRecvTickCount; } }