#include "StdAfx.h" #include "Connection.h" #include "Log.h" #include "DNPacket.h" #include "DNProtocol.h" #include "DNServerDef.h" #include "DNServerProtocol.h" #include "DNSecure.h" #include "SpinBuffer.h" #ifdef _PACKET_COMP #include "zlib.h" #endif #if defined(_SERVER) CConnection::CConnection(void) : m_nSessionID(0), m_pIocpManager(NULL), m_pRecvBuffer(NULL), m_pSendBuffer(NULL), m_bActive(false), m_bDelete(false), m_pSocketContext(NULL), m_bServerConnection(false) #ifdef _PACKET_COMP ,m_pCompBuffer(NULL) ,m_bUseComp(false) #endif ,m_bConnecting(false) ,m_bDetachFlag(false) ,m_hIocp(INVALID_HANDLE_VALUE) { memset(m_DebugInfo, 0, sizeof(_DEBUG_INFO[32])); m_szIP[0] = '\0'; m_wszIP[0] = '\0'; m_wPort = 0; m_DebugInfoCount = 0; m_nStagnatedCount = 0; m_bPushSendQueue = false; SecureLib_InitSA(&m_ClientSA); } CConnection::~CConnection(void) { Final(); } int CConnection::Init(int nRecvLen, int nSendLen, int nCompLen) { Final(); if (nRecvLen < 8192) nRecvLen = 8192; if (nSendLen < 8192) nSendLen = 8192; if (nCompLen < 6144) nCompLen = 6144; #if defined( _DBSERVER ) || defined( _LOGSERVER ) || defined( _CASHSERVER ) UINT uiAccessThreadCount = THREADMAX; #else UINT uiAccessThreadCount = 1; #endif m_pRecvBuffer = new (std::nothrow)CTcpRecvSpinBuffer( uiAccessThreadCount, nRecvLen ); if (!m_pRecvBuffer) return -1; m_SendSync.Lock(); m_pSendBuffer = new CBuffer(nSendLen); if (!m_pSendBuffer) { m_SendSync.UnLock(); return -1; } m_SendSync.UnLock(); #ifdef _PACKET_COMP //瘤陛篮 蜡历侩 牧池记俊父 措览钦聪促. if (nCompLen > 0) { m_pCompBuffer = new (std::nothrow)CCompPacketBuffer( 1, nCompLen ); if (!m_pCompBuffer) return -1; } #endif return 0; } void CConnection::Final() { SAFE_DELETE(m_pRecvBuffer); #ifdef _PACKET_COMP SAFE_DELETE(m_pCompBuffer); #endif m_SendSync.Lock(); SAFE_DELETE(m_pSendBuffer); m_SendSync.UnLock(); if (m_pSocketContext && m_pIocpManager) m_pIocpManager->ClearSocketContext(m_pSocketContext); m_bActive = m_bServerConnection = false; } int CConnection::AddRecvData( CSocketContext* pSocketContext ) { #if defined(_LOGINSERVER) if (m_bDetachFlag == true) return COMPLETE; #else if (m_bDetachFlag == true) return COMPLETE; #endif // #if defined(_LOGINSERVER) if( m_pRecvBuffer->Push( pSocketContext ) < 0 ) return -1; return COMPLETE; } int CConnection::AddRecvData( const DNTPacket& Packet ) { if( m_pRecvBuffer->Push( Packet ) < 0 ) return -1; return COMPLETE; } int CConnection::AddRecvData( const DNEncryptPacketSeq& Packet ) { if( m_pRecvBuffer->Push( Packet ) < 0 ) return -1; return COMPLETE; } int CConnection::AddSendData(int iMainCmd, int iSubCmd, char *pData, int iLen, TParamData* pParamData, BYTE cSeq, bool bForceUncomp) { if (GetDetachFlag()) return -1; _ASSERT(iMainCmd < 255); _ASSERT(iSubCmd < 255); _ASSERT(iLen>=0); int Ret = 0; int nBufLen = 0; if (GetDelete()) return -1; if( !GetActive() ) return -1; if (m_pIocpManager && m_pSocketContext && (m_pSocketContext->m_Socket != INVALID_SOCKET)) { switch (m_pSocketContext->m_dwKeyParam) { case CONNECTIONKEY_USER: // 蜡历绰 鞠龋拳 { #ifdef _PACKET_COMP if (m_bUseComp && bForceUncomp == false) { if (m_pCompBuffer && iLen > COMPRESSMINSIZE) { DNTCompPacket packet; memset(&packet, 0, sizeof(packet)); packet.header.cSeq = cSeq; packet.header.cMainCmd = static_cast(iMainCmd); packet.header.cSubCmd = static_cast(iSubCmd); UINT nLeftBuffetrSize = ((CCompPacketBuffer*)m_pCompBuffer)->GetLeftBufferSize(); UINT nCompPacketSize = sizeof(packet.buf); compress2((Bytef*)&packet.buf, (uLongf*)&nCompPacketSize, (Bytef*)pData, (uLongf)iLen, Z_BEST_SPEED); packet.header.nLen = static_cast(sizeof(DNTPacketCompHeader) + nCompPacketSize); if (packet.header.nLen > nLeftBuffetrSize) FlushCompData(); Ret = m_pCompBuffer->Push(packet); } else return AddSendData(iMainCmd, iSubCmd, pData, iLen, pParamData, cSeq, true); } else #endif { #ifdef _PACKET_COMP //鉴辑焊厘阑 困秦辑 阶咯乐绰 滚欺啊 乐栏搁 刚历 敲矾教茄促. if (m_pCompBuffer) FlushCompData(); #endif if( pParamData && pParamData->bEncrypt ) { m_SendSync.Lock(); Ret = m_pSendBuffer->Push( (char*)&pParamData->sEncrypt, pParamData->sEncrypt.nLen, true ); m_SendSync.UnLock(); nBufLen = pParamData->sEncrypt.nLen; } else { DNEncryptPacketSeq EnPacket = { 0, }; EnPacket.cSeq = cSeq; EnPacket.Packet.iLen = static_cast(sizeof(DNTPacketHeader)+iLen); EnPacket.Packet.cMainCmd = static_cast(iMainCmd); EnPacket.Packet.cSubCmd = static_cast(iSubCmd); if( iLen < 0 || iLen > sizeof(EnPacket.Packet.buf) ) { _DANGER_POINT_MSG( L"if( iLen < 0 || iLen > sizeof(EnPacket.Packet.buf) )" ); //_DANGER_POINT(); return -1; } memcpy(&EnPacket.Packet.buf, pData, iLen); EnPacket.nLen = EnPacket.Packet.iLen + sizeof(BYTE) + sizeof(USHORT); CDNSecure::GetInstance().Tea_encrypt( reinterpret_cast(&EnPacket.Packet), EnPacket.Packet.iLen ); if (EnPacket.nLen > 0) { DWORD dwTime = timeGetTime(); do { bool bIncreaseBuffer = false; // 吝惫 VVIP 蜡历 锭巩俊 某矫牢亥府胶飘 抗寇贸府 if( iMainCmd == SC_ITEM && iSubCmd == eItem::SC_CASHINVENLIST ) bIncreaseBuffer = true; m_SendSync.Lock(); Ret = m_pSendBuffer->Push( (char*)&EnPacket, EnPacket.nLen, true, bIncreaseBuffer ); m_SendSync.UnLock(); // 滚欺何练 if( Ret == -2 ) { FlushSendData(); } }while( Ret < 0 && timeGetTime()-dwTime<1000 ); } else Ret = -1; //encrypt failed if (Ret < 0) _ASSERT(0); nBufLen = EnPacket.nLen; if( pParamData && pParamData->bEncrypt == false ) { memcpy( &pParamData->sEncrypt, &EnPacket, EnPacket.nLen ); pParamData->bEncrypt = true; } } } } break; #ifdef PRE_ADD_DOORS case CONNECTIONKEY_DOORS: { DNDoorsPacketHeader dnDoors; memset(&dnDoors, 0, sizeof(DNDoorsPacketHeader)); dnDoors.datasize = static_cast(sizeof(DNDoorsPacketHeader) + iLen); dnDoors.protocol = static_cast(iMainCmd); m_SendSync.Lock(); Ret = m_pSendBuffer->Push( (char*)&dnDoors, sizeof(DNDoorsPacketHeader) ); // 庆歹 if( Ret == 0 && iLen > 0 ) Ret = m_pSendBuffer->Push( pData, iLen ); // 单捞磐 m_SendSync.UnLock(); nBufLen = dnDoors.datasize; } break; #endif // #ifdef PRE_ADD_DOORS default: // 弊寇绰 鞠龋拳 救茄促 { DNTPacketHeader dnHeader; dnHeader.iLen = static_cast(sizeof(dnHeader)+iLen); dnHeader.cMainCmd = static_cast(iMainCmd); dnHeader.cSubCmd = static_cast(iSubCmd); m_SendSync.Lock(); Ret = m_pSendBuffer->Push( (char*)&dnHeader, sizeof(dnHeader) ); // 庆歹 if( Ret == 0 && iLen > 0 ) Ret = m_pSendBuffer->Push( pData, iLen ); // 单捞磐 m_SendSync.UnLock(); nBufLen = dnHeader.iLen; } break; } if (Ret == 0) { m_pIocpManager->m_nAddSendBufSize += nBufLen; m_pIocpManager->AddSendCall(m_pSocketContext); } else if (Ret < 0) m_pIocpManager->DetachSocket(m_pSocketContext, L"AddSendData Error"); } return Ret; } #if (defined(_KR) || defined(_US)) && (defined(_LOGINSERVER) || defined(_MASTERSERVER) || defined(_CASHSERVER)) int CConnection::AddSendData(char *pData, int nLen) { int Ret = 0; if (GetDelete()) return -1; if (m_pIocpManager && m_pSocketContext && (m_pSocketContext->m_Socket != INVALID_SOCKET)) { m_SendSync.Lock(); Ret = m_pSendBuffer->Push( pData, nLen ); // 单捞磐 m_SendSync.UnLock(); if (Ret == 0) { m_pIocpManager->m_nAddSendBufSize += nLen; m_pIocpManager->AddSendCall(m_pSocketContext); } else if (Ret < 0) m_pIocpManager->DetachSocket(m_pSocketContext, L"AddSendData Error"); } return Ret; } #endif // 2009.01.23 辫逛 // FlushSendData() 窃荐俊辑 沥惑利栏肺 Send啊 己傍沁芭唱 焊尘 单捞磐啊 绝栏搁 0阑 府畔窍绊 弊 捞寇狼 版快俊绰 0 捞 酒囱蔼阑 府畔秦辑 // SendThread 俊辑 queue 厚况瘤瘤 臼霸 贸府秦霖促. int CConnection::FlushSendData() { if (m_pSocketContext && m_pIocpManager) { //泅犁 备炼肺绰 send Thread窜俊辑狼 撅技胶涝聪促. SendBuffer俊 扁夯利栏肺 磊林 撅技胶 登绰 镑篮 ProcessThread客 //SendThread啊 登摆嚼聪促酒~ ScopeLock Lock( m_SendSync ); int nSize = GetSendCount(); if (nSize <= 0) { if (GetConnectionKey() == CONNECTIONKEY_USER && GetDetachFlag()) return -1; return 0; } #ifdef _USE_SENDCONTEXTPOOL ScopeLock SendLock(m_pSocketContext->m_SendIOLock); while (1) { nSize = GetSendCount(); if (nSize > 0) { TIOContext * pContext = m_pSocketContext->GetSendIO(); if (pContext) { pContext->Len = ViewSendData(pContext->buffer, INTERNALBUFFERLENMAX); if(pContext->Len > 0) { int PostSendRet = m_pIocpManager->PostSend(m_pSocketContext, pContext); //PostSend甫 Call窍搁辑 角犁 AsyncroSend甫 窍霸 邓聪促. if( PostSendRet == 0 ) { //buffer skip SkipSendData(pContext->Len); //SendCount Test Codes m_pIocpManager->m_nPostSendSize += pContext->Len; nSize = 0; } else { m_pSocketContext->ReleaseSendIO(pContext, pContext->Len); //Context甫 倒妨林绊 促矫 倒霸 茄促. #if defined( PRE_FIX_SOCKETCONTEXT_DANGLINGPTR ) if( PostSendRet == IN_DISCONNECT ) return IN_DISCONNECT; #endif // #if defined( PRE_FIX_SOCKETCONTEXT_DANGLINGPTR ) return 1; } } else { //墨款飘 眉农甫 固府窍绊 甸绢 吭绰单 捞矾搁 救旦. _DANGER_POINT(); m_pSocketContext->ReleaseSendIO(pContext, pContext->Len); //Context甫 倒妨林绊 促矫 倒霸 茄促. return 1; } } else { // 肺弊 眠啊 //_DANGER_POINT(); return 1; } } else { if (GetConnectionKey() == CONNECTIONKEY_USER && GetDetachFlag()) return -1; return 0; } } #else if (m_pSocketContext->m_SendIO.Len == 0) { //IOLen狼 Decrease绰 IOCP(窍困俺充)窜俊辑 SendComplete啊 哆搁 临绢奠聪促. 弊矾聪鳖 捞犯霸 登搁 哪敲复捞 哆瘤 臼栏搁, //SendProcess绰 Block登柳 臼栏唱 促澜 畔栏肺 逞绢 啊霸 邓聪促. //弊烦 complete啊 冻绢瘤瘤 臼绰促搁 拌加 阶捞霸 登绰 备炼...... m_pSocketContext->m_SendIO.Len = ViewSendData(m_pSocketContext->m_SendIO.buffer, INTERNALBUFFERLENMAX); if( m_pSocketContext->m_SendIO.Len > 0 ) { //PostSend甫 Call窍搁辑 角犁 AsyncroSend甫 窍霸 邓聪促. if( m_pIocpManager->PostSend(m_pSocketContext) == 0 ) { //SendCount Test Codes m_pIocpManager->m_nPostSendSize += m_pSocketContext->m_SendIO.Len; } } if (GetConnectionKey() == CONNECTIONKEY_USER && GetDetachFlag() && GetSendCount() <= 0) return -1; return 0; } #endif } return 1; } #ifdef _USE_SENDCONTEXTPOOL bool CConnection::SendComplete(TIOContext * pContext, int nSize) { ScopeLock Lock( m_SendSync ); return m_pSocketContext->ReleaseSendIO(pContext, nSize); } #else bool CConnection::SendComplete(int nSize) { ScopeLock Lock( m_SendSync ); SkipSendData(nSize); m_pSocketContext->m_SendIO.Len -= nSize; if (m_pSocketContext->m_SendIO.Len == 0) return false; return true; } #endif int CConnection::GetSendCount() { return m_pSendBuffer->GetCount(); } int CConnection::ViewSendData(char *pData, int nMaxSize) { // 惑困俊辑 悼扁拳 登绰 窃荐 int Size = m_pSendBuffer->GetCount(); if (Size > 0){ if (Size > nMaxSize) Size = nMaxSize; m_pSendBuffer->View(pData, Size); } return Size; } void CConnection::SkipSendData(int nSize) { // 惑困俊辑 悼扁拳 登绰 窃荐 m_pSendBuffer->Skip(nSize); } bool CConnection::FlushRecvData(ULONG nCurTick) { #ifdef _USE_ACCEPTEX ScopeLock Lock( m_FlushRecvDataLock ); #endif ScopeSpinBufferSwitch Scope( m_pRecvBuffer ); char* pBuffer = Scope.pGetBuffer(); UINT uiSize = Scope.uiGetSize(); int nCnt = 0, nElapsed = 0, nBufLen = 0; int nRet = ERROR_UNKNOWN_HEADER, nElapsedTick = 0; while( uiSize ) { if (m_pSocketContext->m_dwKeyParam == CONNECTIONKEY_USER){ // 蜡历绰 鞠龋拳 DNEncryptPacketSeq * pEnPacket = (DNEncryptPacketSeq*)pBuffer; int nLen = pEnPacket->nLen - sizeof(BYTE) - sizeof(USHORT); // BufferOverrun if( nLen <= 0 || static_cast(uiSize) < pEnPacket->nLen ) { g_Log.Log( LogType::_ERROR, L"## FlushRecvData() BufferOverRun Check-1!!!" ); return false; } CDNSecure::GetInstance().Tea_decrypt( reinterpret_cast(&pEnPacket->Packet), nLen ); if( pEnPacket->Packet.cMainCmd == IN_DISCONNECT || nLen <= 0 ) return false; nElapsedTick = 0; nRet = FlushRecvMessage( (char*)&pEnPacket->Packet, nElapsedTick, nCurTick ); //蜡历牢 版快俊父 谗绢滚赴促. //if (nRet == ERROR_INVALIDPACKET || nRet == ERROR_UNKNOWN_HEADER) if (nRet == ERROR_INVALIDPACKET ) { DNTPacket * pPacket = (DNTPacket*)&pEnPacket->Packet; g_Log.Log( LogType::_ERROR, 0, 0, 0, GetSessionID(), L"## Invalid Packet RETCODE:%d SID:%u MCMD:%d SCMD:%d\r\n", nRet, GetSessionID(), pPacket->cMainCmd, pPacket->cSubCmd); return false; //咯扁辑 谗绢瘤搁 贸府窍瘤 臼绰 菩哦阑 荐脚窍芭唱 菩哦捞 嘎瘤 臼绰巴. } nElapsed += nElapsedTick; nBufLen = pEnPacket->nLen; } #ifdef PRE_ADD_DOORS else if (m_pSocketContext->m_dwKeyParam == CONNECTIONKEY_DOORS) { DNDoorsPacket * pPacket = reinterpret_cast(pBuffer); nRet = MessageProcess(pPacket->header.protocol, 0, pPacket->data, pPacket->header.datasize - (int)(sizeof(*pPacket) - sizeof(pPacket->data)));; nBufLen = pPacket->header.datasize; } #endif //#ifdef PRE_ADD_DOORS else { // 弊寇绰 鞠龋拳 救茄促 DNTPacket* pHeader = reinterpret_cast(pBuffer); if( pHeader->cMainCmd == IN_DISCONNECT ) return false; nElapsedTick = 0; nRet = FlushRecvMessage( pBuffer, nElapsedTick, nCurTick ); nElapsed += nElapsedTick; nBufLen = pHeader->iLen; } // BufferOverrun if( static_cast(uiSize) < nBufLen ) { g_Log.Log( LogType::_ERROR, L"## FlushRecvData() BufferOverRun Check-2!!!" ); return false; } pBuffer += nBufLen; uiSize -= nBufLen; nCnt++; } if (nCnt > STORED_RECV_LIMIT && nElapsed > STORED_RECV_ELAPSED_TICK) { if (m_nStagnatedCount > STAGNATED_DISCONNECT_COUNT) m_pIocpManager->StagnatePacket(nCnt, nElapsed, m_pSocketContext); else m_nStagnatedCount++; } else m_nStagnatedCount = 0; return true; } #if defined (_DBSERVER) || defined (_LOGSERVER) || defined(_CASHSERVER) bool CConnection::FlushDBData( int nThreadID ) { ScopeSpinBufferSwitch Scope( m_pRecvBuffer ); char* pBuffer = Scope.pGetBuffer(); UINT32 uiSize = Scope.uiGetSize(); while( uiSize ) { DNTPacket* pHeader = reinterpret_cast(pBuffer); if( pHeader->cMainCmd == IN_DISCONNECT ) return false; DBMessageProcess( pBuffer, nThreadID ); pBuffer += pHeader->iLen; uiSize -= pHeader->iLen; } return true; } #endif // #if defined (_DBSERVER) #if defined(_KR) && (defined(_LOGINSERVER) || defined(_MASTERSERVER)) bool CConnection::FlushAuthData() { ScopeSpinBufferSwitch Scope( m_pRecvBuffer ); char* pBuffer = Scope.pGetBuffer(); UINT uiSize = Scope.uiGetSize(); while( uiSize ) { TAuthHeader *pHeader = reinterpret_cast(pBuffer); USHORT wLength = SWAP16(pHeader->wLength) + 3; MessageProcess(0, 0, pBuffer, uiSize); pBuffer += wLength; uiSize -= wLength; } return true; } #elif defined(_CASHSERVER) && (defined(_KR) || defined(_US)) bool CConnection::FlushBillingData() { ScopeSpinBufferSwitch Scope( m_pRecvBuffer ); char* pBuffer = Scope.pGetBuffer(); UINT uiSize = Scope.uiGetSize(); while( uiSize ) { TBillingHeader *pHeader = reinterpret_cast(pBuffer); UINT nLength = SWAP32(pHeader->nLength) + 5; MessageProcess(0, 0, pBuffer, uiSize); pBuffer += nLength; uiSize -= nLength; } return true; } #endif #if defined(_TW) bool CConnection::FlushAuthData_TW() { ScopeSpinBufferSwitch Scope( m_pRecvBuffer ); char* pBuffer = Scope.pGetBuffer(); UINT uiSize = Scope.uiGetSize(); while( uiSize ) { // \r\n 阑 扁霖栏肺 颇教窍档废 荐沥 鞘夸 !!! USHORT wLength = 0; for (INT iIndex = 0 ; (static_cast(uiSize) - 1) > iIndex ; ++iIndex) { if ('\r' == pBuffer[iIndex] && '\n' == pBuffer[iIndex + 1]) { wLength = iIndex + 2; pBuffer[iIndex] = '\0'; break; } } if (!wLength) { return false; } MessageProcess(0, 0, pBuffer, uiSize); pBuffer += wLength; uiSize -= wLength; } return true; } #endif // #if defined(_TW) #if defined(_TH) bool CConnection::FlushAuthData_TH() { ScopeSpinBufferSwitch Scope( m_pRecvBuffer ); char* pBuffer = Scope.pGetBuffer(); UINT uiSize = Scope.uiGetSize(); while( uiSize ) { USHORT wLength = 0; for (INT iIndex = 0 ; (static_cast(uiSize)) > iIndex ; ++iIndex) { if (';' == pBuffer[iIndex]) { wLength = iIndex + 1; pBuffer[iIndex] = '\0'; break; } } if (!wLength) { return false; } MessageProcess(0, 0, pBuffer, wLength); pBuffer += wLength; uiSize -= wLength; } return true; } bool CConnection::FlushOTPData_TH() { ScopeSpinBufferSwitch Scope( m_pRecvBuffer ); char* pBuffer = Scope.pGetBuffer(); UINT uiSize = Scope.uiGetSize(); pBuffer[uiSize-1] = '\0'; MessageProcess(0, 0, pBuffer, uiSize); pBuffer += uiSize; uiSize -= uiSize; return true; } #endif // #if defined(_TW) #ifdef _PACKET_COMP void CConnection::SetPacketComp(bool bComp) { if (m_pCompBuffer == NULL) return; if (bComp == false) { FlushCompData(); m_bUseComp = false; } else m_bUseComp = true; } void CConnection::FlushCompData() { if (m_pCompBuffer == NULL) return; ScopeSpinBufferSwitch Scope(m_pCompBuffer); char* pBuffer = Scope.pGetBuffer(); UINT32 uiSize = Scope.uiGetSize(); if (uiSize <= 0) return; DNEncryptPacketSeq EnPacket = { 0, }; m_SendSync.Lock(); EnPacket.cSeq = COMPRESSPACKET; memcpy(&EnPacket.Buf, pBuffer, uiSize); EnPacket.nLen = EnPacket.Packet.iLen + sizeof(BYTE) + sizeof(USHORT); CDNSecure::GetInstance().Tea_encrypt( reinterpret_cast(&EnPacket.Packet), EnPacket.Packet.iLen ); int Ret = 0; if (EnPacket.nLen > 0) Ret = m_pSendBuffer->Push( (char*)&EnPacket, EnPacket.nLen, true ); else Ret = -1; m_SendSync.UnLock(); if (Ret < 0) _ASSERT(0); int nBufLen = EnPacket.nLen; if (Ret == 0) { m_pIocpManager->m_nAddSendBufSize += nBufLen; m_pIocpManager->AddSendCall(m_pSocketContext); } else if (Ret < 0) m_pIocpManager->DetachSocket(m_pSocketContext, L"AddSendData Error"); } #endif int CConnection::FlushRecvMessage(char * pData, int &nElapsedTick, ULONG nCurTick) { DNTPacket * pPacket = (DNTPacket*)pData; int cnt = m_DebugInfoCount++&31; m_DebugInfo[cnt]._DebugMainCmd = pPacket->cMainCmd; m_DebugInfo[cnt]._DebugSubCmd = pPacket->cSubCmd; m_DebugInfo[cnt]._DebugTick = nCurTick; int nRet = MessageProcess(pPacket->cMainCmd, pPacket->cSubCmd, pPacket->buf, pPacket->iLen - (int)(sizeof(*pPacket) - sizeof(pPacket->buf))); //test if (m_pIocpManager && m_pSocketContext->m_dwKeyParam == CONNECTIONKEY_USER) m_pIocpManager->m_nProcessBufSize += pPacket->iLen; return nRet; } void CConnection::SetSocketContext(CIocpManager *pIocpManager, CSocketContext *pSocketContext) { m_pIocpManager = pIocpManager; m_pSocketContext = pSocketContext; } void CConnection::BufferClear() { m_SendSync.Lock(); if (m_pSendBuffer) m_pSendBuffer->Clear(); m_SendSync.UnLock(); m_pRecvBuffer->Clear(); } void CConnection::RecvBufferClear() { m_pRecvBuffer->Clear(); } void CConnection::SendBufferClear() { m_SendSync.Lock(); if (m_pSendBuffer) m_pSendBuffer->Clear(); m_SendSync.UnLock(); } void CConnection::DetachConnection(wchar_t *pwszIdent) { printf("[DETACH_CONNECTION] : %ws \n",pwszIdent); return; if( pwszIdent && wcslen(pwszIdent) > 0) m_pSocketContext->SetDetachReason(pwszIdent); m_pIocpManager->DetachSocket(m_pSocketContext, pwszIdent == NULL ? const_cast(m_wstrDelayDetachReson.c_str()) : pwszIdent); } void CConnection::DelayDetachConnection(wchar_t *pwszIdent) { if (GetConnectionKey() == CONNECTIONKEY_USER) { m_wstrDelayDetachReson.clear(); m_wstrDelayDetachReson = pwszIdent; m_bDetachFlag = true; } } void CConnection::SetDelete(bool bDelete) { m_DeleteLock.Lock(); m_bDelete = bDelete; m_DeleteLock.UnLock(); } bool CConnection::GetDelete() { m_DeleteLock.Lock(); bool bDelete = m_bDelete; m_DeleteLock.UnLock(); return bDelete; } DWORD CConnection::GetConnectionKey() { if (m_pSocketContext) return m_pSocketContext->m_dwKeyParam; else return CONNECTIONKEY_DEFAULT; } #endif // #if defined(_SERVER)