#include "StdAfx.h" #include "DataProcess.h" #include "SockProcess.h" #include HANDLE g_hStdOut; unsigned int CRunDataProcesser::s_nSndThreadSleepTime = 20; extern bool g_ServerIsRunning; //接收数据的线程 #ifdef _MSC_VER VOID STDCALL CRunDataProcesser::RecvDataProcdaessRoutine(void *arg) #else VOID* CRunDataProcesser::RecvDataProcessRoutine(void *arg) #endif { CRunDataProcesser * pRunData = (CRunDataProcesser *)arg; //LPCRITICAL_SECTION pQueueLock; CBaseList *pRecvList; PCLIENTRECVBUF *ppRecvBufs, pRecvBuf; PRUNGATEUSERSESSION pSession; INT_PTR nBufferCount; TICKCOUNT dwProcStartTick, dwLockDataTick, dwLockCheckTick, dwSendCheckTick, dwPerfDumpTick, dwSendGateUserInfo; //pQueueLock = &pRunData->m_RecvQueueLock; pRecvList = pRunData->m_pRecvProcList; pRunData->m_llSendKeepAliveTime = 0; dwLockDataTick = dwLockCheckTick = dwPerfDumpTick = dwSendGateUserInfo = _getTickCount(); dwSendCheckTick = dwSendGateUserInfo + 2000; while ( !pRunData->m_boStoping ) { dwProcStartTick = _getTickCount(); //发送网关自检 if ( dwProcStartTick - dwSendCheckTick >= 2000 ) { pRunData->SendCheck( GM_CHECKSERVER ); dwSendCheckTick = dwProcStartTick; pRunData->m_llSendKeepAliveTime = dwSendCheckTick; } // 发送网关用户数目,一分钟发一次 if (dwProcStartTick - dwSendGateUserInfo >= 60000 ) { pRunData->SendGateUserInfo(); dwSendGateUserInfo = dwProcStartTick; } //检查会话关闭 if ( dwProcStartTick - dwLockCheckTick >= 5000 ) { if ( pRunData->CheckCloseSessions( dwProcStartTick - dwLockCheckTick >= 10000 ) ) { dwProcStartTick = dwLockCheckTick = _getTickCount(); } } // dump statistic if (dwProcStartTick - dwPerfDumpTick >= 120000) { CTimeProfMgr::getSingleton().dump(); dwPerfDumpTick = dwProcStartTick; } //如果未能获得数据队列锁则让出本次CPU时间 if ( !TryEnterCriticalSection( &pRunData->m_RecvQueueLock ) ) { if ( dwProcStartTick - dwLockDataTick < 60 ) { Sleep( 1 ); continue; } else { EnterCriticalSection( &pRunData->m_RecvQueueLock ); dwProcStartTick = dwLockDataTick = _getTickCount(); } } else dwLockDataTick = dwProcStartTick; //交换数据处理队列 pRecvList = pRunData->m_pRecvAppendList; pRunData->m_pRecvAppendList = pRunData->m_pRecvProcList; pRunData->m_pRecvProcList = pRecvList; LeaveCriticalSection( &pRunData->m_RecvQueueLock ); //如果没有待处理的数据则让出本次CPU时间 nBufferCount = pRecvList->count(); if ( !nBufferCount ) { Sleep( 1 ); continue; } ppRecvBufs = (PCLIENTRECVBUF*)(void**)(*pRecvList); while ( nBufferCount > 0 ) { pRecvBuf = *ppRecvBufs; nBufferCount--; ppRecvBufs++; pSession = pRecvBuf->pSession; if ( pRecvBuf->nBufferSize > 0 ) { //如果会话被关闭或效验过期则不予处理 if ( pSession->nSocket != INVALID_SOCKET && pSession->nVerifyIdx == pRecvBuf->nVerify && !pSession->boMarkToClose && !pSession->boRemoteClosed ) { pSession->dwClientMsgTick = dwProcStartTick; //OutputMsg( rmTip, "dwProcStartTick=%I64d",dwProcStartTick); pRunData->ProcessUserRecvPacket( pSession, (char*)(pRecvBuf + 1), pRecvBuf->nBufferSize ); pSession->nRecvPacketCount++; } } free( pRecvBuf ); } pRecvList->clear(); pRunData->m_dwLastProcUsrMsgTime = _getTickCount() - dwProcStartTick; //循环小于指定时间则休眠一次 //if ( pRunData->m_dwLastProcUsrMsgTime < 16 ) if(TRUE) { Sleep ( 1 ); } } ExitThread( 0 ); } //发送数据的线程 #ifdef _MSC_VER VOID STDCALL CRunDataProcesser::SendDataProcessRoutine(void* arg) #else VOID* CRunDataProcesser::SendDataProcessRoutine(void* arg) #endif { PRUNDATASENDTHREAD pRunThread = (PRUNDATASENDTHREAD)arg; TICKCOUNT dwProcStartTick; CRunDataProcesser *pRunData; int nLockSendBufQLockFail = 0; pRunData = pRunThread->pRunData; (void)signal(SIGPIPE, SIG_IGN); while ( !pRunData->m_boStoping ) { dwProcStartTick = _getTickCount(); if ( pRunData->CopyWaitSendBuffers( pRunThread, TRUE) ) nLockSendBufQLockFail = 0; else nLockSendBufQLockFail ++; pRunData->CheckSendSessionBuffers( pRunThread ); //循环小于指定时间则休眠一次 pRunThread->dwProcTick = _getTickCount() - dwProcStartTick; //if ( pRunThread->dwProcTick < 20 ) { dwProcStartTick = _getTickCount(); Sleep(s_nSndThreadSleepTime); TICKCOUNT curTick = _getTickCount(); pRunThread->dwSleepTick = curTick - dwProcStartTick; } /*else pRunThread->dwSleepTick = 0;*/ } ExitThread( 0 ); } //收到了服务器的数据,进行处理 //VOID CRunDataProcesser::ProcessRecvBuffers(const GateMsg* msg) VOID CRunDataProcesser::ProcessRecvBuffers(const GATEMSGHDR* pHeader, LPCSTR pData, size_t nLen) { Assert(pHeader->dwGateCode == RUNGATECODE); /*if (msg->header.wIdent == GM_DATA) Assert(msg->header.wTemp == RUNTEMPCODE);*/ if (s_nIgnoreDataPacket) return; //如果是关闭服务器的话 if(pHeader->wIdent ==GM_CLOSE_SERVER) { OutputMsg(rmTip,"Back server close from back"); g_ServerIsRunning =false; return; } else if (pHeader->wIdent == GM_APPBIGPACK) { char* pBuffEnd = (char *)pData + nLen; GATEMSGHDR* pCurHeader = (GATEMSGHDR *)pData; while ((char*)pCurHeader < pBuffEnd) { if (pCurHeader->dwGateCode != RUNGATECODE) { OutputMsg(rmError, _T("%s recv packet invalid..."), __FUNCTION__); break; } DispathRecvMessage(pCurHeader, (const char*)(pCurHeader+1), pCurHeader->nDataSize); pCurHeader = (GATEMSGHDR *)((char *)pCurHeader + (sizeof(GATEMSGHDR) + pCurHeader->nDataSize)); } } else DispathRecvMessage((GATEMSGHDR * const)pHeader, pData, nLen); //DECLARE_FUN_TIME_PROF(); //if (s_nIgnoreDataPacket) //{ // Inherited::ProcessRecvBuffers(pDataBuffer); // SwapRecvProcessBuffers(); // return; //} // //INT_PTR nLen, nCheckMsgLen; //char *pBuf, *pMsgBuf; //PGATEMSGHDR pMsgHdr; //BOOL boTipNotRunGateCode; ////如果连接已断开则丢弃所有数据 //if ( !connected() ) //{ // OutputMsg( rmWaning, _T("ProcessRecvBuffers,socket is close ,drop data") ); // Inherited::ProcessRecvBuffers(pDataBuffer); // SwapRecvProcessBuffers(); // return; //} //nLen = 0; //pBuf = NULL; //pBuf = pDataBuffer->pPointer; //nLen = pDataBuffer->nOffset - (pBuf - pDataBuffer->pBuffer); ////处理数据包的条件是接收缓冲的长度不少于一个网关通信消息头 //if ( nLen >= sizeof(*pMsgHdr) ) //{ // boTipNotRunGateCode = FALSE; // while ( TRUE ) // { // pMsgHdr = (PGATEMSGHDR)pBuf; // //检查协议头是否有效(dwGateCode必须是RUNGATECODE) // if ( pMsgHdr->dwGateCode == RUNGATECODE ) // { // if (pMsgHdr->nDataSize >= 0 ) // { // nCheckMsgLen = pMsgHdr->nDataSize + sizeof(*pMsgHdr); // if ( nCheckMsgLen < 0x80000 )//丢弃长度大于0x8000的数据包 // { // boTipNotRunGateCode = FALSE; // if ( nLen < nCheckMsgLen ) // break; // pMsgBuf = pBuf + sizeof(*pMsgHdr); // DispathRecvMessage( pMsgHdr, pMsgBuf, pMsgHdr->nDataSize ); // } // else Assert(0); // } // else // { // Assert(pMsgHdr->nDataSize >= 0); // nCheckMsgLen = sizeof(*pMsgHdr); // } // pBuf += nCheckMsgLen; // nLen -= nCheckMsgLen; // } // else // { // pBuf++; // nLen--; // if ( !boTipNotRunGateCode ) // { // boTipNotRunGateCode = TRUE; // OutputMsg( rmWaning, _T("%s droped a packed(not RUNGATECODE)"), _T(__FUNCTION__) ); // } // } // if ( nLen < sizeof(*pMsgHdr) ) // break; // } // pDataBuffer->pPointer = pBuf; //} //SwapRecvProcessBuffers(); } // 接收服务器数据的线程 /* 以前使用了管道,现在使用socket //xiaoql 2010-11-11日修改 VOID STDCALL CRunDataProcesser::RecvServerProcessRoutine(CRunDataProcesser *pRunData) { #pragma __CPMSG__("----------------基类修改为ClientSocket,则可以去掉这个函数以及对线程的创建") DWORD dwSize, dwBytesRead; HANDLE hPipe; PRUNGATEDATBUF pDataBuf; DWORD dwPipeConnectTick = 0; DWORD dwProcStartTick; pDataBuf = &pRunData->m_ServerBuf; while ( !pRunData->m_boStoping ) { dwProcStartTick = _getTickCount(); hPipe = pRunData->m_hPipe; if ( hPipe == INVALID_HANDLE_VALUE ) { Sleep( 16 ); if ( dwProcStartTick - dwPipeConnectTick >= 3000 ) { if ( !pRunData->OpenServerPipe() ) dwPipeConnectTick = _getTickCount(); else OutputMsg( rmTip, "LogicServer Pipe conencted" ); } continue; } //如果管道没有数据则让出处理器时间 dwSize = GetFileSize( hPipe, NULL ); if ( !dwSize ) { Sleep( 1 ); pRunData->m_dwProcSrvThreadSleep = _getTickCount() - dwProcStartTick; continue; } else if ( dwSize == INVALID_FILE_SIZE ) { pDataBuf->nOffset = 0; pRunData->GotError( __FUNCTION__, "GetFileSize", GetLastError() ); pRunData->ServerPipeError(); continue; } pRunData->m_dwProcSrvThreadSleep = 0; //增长接受数据包 if ( pDataBuf->nSize < pDataBuf->nOffset + (int)dwSize ) { pDataBuf->nSize += (dwSize / 1024 + 1) * 1024; pDataBuf->lpBuffer = (char*)realloc( pDataBuf->lpBuffer, pDataBuf->nSize ); } //循环读取数据 while ( TRUE ) { if ( !ReadFile( hPipe, &pDataBuf->lpBuffer[pDataBuf->nOffset], dwSize, &dwBytesRead, NULL ) ) { pDataBuf->nOffset = 0; pRunData->GotError( __FUNCTION__, "ReadFile", GetLastError() ); pRunData->ServerPipeError(); break; } pDataBuf->nOffset += dwBytesRead; if ( dwBytesRead >= dwSize ) break; } InterlockedExchange( (LONG*)&pRunData->m_dwLastRecvSrvMsgTime, _getTickCount() - dwProcStartTick ); InterlockedExchangeAdd( (LONG*)&pRunData->m_dwRecvSeverSize, dwSize ); //处理数据 if ( pDataBuf->nOffset ) { pRunData->ProcessServerPacket(); } } ExitThread( 0 ); } */ VOID CRunDataProcesser::DispathRecvMessage(const PGATEMSGHDR pMsgHdr, const char *pBuffer, SIZE_T nBufSize) { PRUNGATEUSERSESSION pSession; /* if(GM_DATA ==pMsgHdr->wIdent) { OutputMsg(rmTip, _T("收到后台数据,cmd=%d,wSessionIdx=%d,wServerIdx=%d,socket=%d\n"), pMsgHdr->wIdent, pMsgHdr->wSessionIdx,pMsgHdr->wServerIdx,pMsgHdr->nSocket); } */ switch ( pMsgHdr->wIdent ) { case GM_CLOSE: if ( pMsgHdr->wSessionIdx < m_nMaxSessionCount ) { pSession = &m_Sessions[pMsgHdr->wSessionIdx]; if ( pSession->nSocket == pMsgHdr->nSocket && !pSession->boMarkToClose && !pSession->boRemoteClosed ) { SendCloseSession( pSession, FALSE, enReasonGM ); } else { OutputMsg( rmWaning, _T("GM_CLOSE socket不匹配 wSessionIdx=%d,本地Socket=%d,后台的为%d"), pMsgHdr->wSessionIdx, pSession->nSocket, pMsgHdr->nSocket ); } } break; case GM_CHECKCLIENT: { // 保存服务器的时间 if (m_llSendKeepAliveTime > 0) { if (m_nCheckTimeCount < 10) { TICKCOUNT nTimeDiff = pMsgHdr->tickCount - _getTickCount(); m_llOccuTimeDiff += nTimeDiff; m_nCheckTimeCount++; m_llSvrTimeDiff = (long long)(m_llOccuTimeDiff / (float)m_nCheckTimeCount); OutputMsg(rmNormal, _T("timediff=%lld,result dif=%lld,checkTimecount=%d"), nTimeDiff, m_llSvrTimeDiff, m_nCheckTimeCount); } } /*OutputMsg(rmNormal, _T("------logicSvrTime=%I64d gateTime=%I64d, timeDif=%I64d"), pMsgHdr->tickCount, nCurrTick, m_llSvrTimeDiff);*/ } break; case GM_APPKEEPALIVE: { // 给服务器会应答消息 pSession = &m_Sessions[pMsgHdr->wSessionIdx]; if ( pSession->nSocket == pMsgHdr->nSocket && !pSession->boMarkToClose && !pSession->boRemoteClosed ) { SendKeepAliveAck( pSession, pBuffer, nBufSize); } break; } case GM_SERVERUSERINDEX: if ( pMsgHdr->wSessionIdx < m_nMaxSessionCount ) { pSession = &m_Sessions[pMsgHdr->wSessionIdx]; if ( pSession->nSocket == pMsgHdr->nSocket && !pSession->boMarkToClose && !pSession->boRemoteClosed ) { pSession->nServerIdx = pMsgHdr->wServerIdx; OutputMsg(rmNormal, _T("recv GM_ServerIndex msg. socket=%d, sessionId=%d, set serverIdx=%d"), (int)pSession->nSocket, (int)pSession->nIndex, pSession->nServerIdx); } else { OutputMsg(rmError, _T("GM_ServerIndex Error, session closed or socket unmatch(session socket=%d, sessionId=%d, msghdr socket=%d"), (int)pSession->nSocket, (int)pSession->nIndex, (int)pMsgHdr->nSocket); } } break; case GM_DATA: if ( pMsgHdr->wSessionIdx < m_nMaxSessionCount ) { pSession = &m_Sessions[pMsgHdr->wSessionIdx]; if ( !pSession->boMarkToClose && !pSession->boRemoteClosed ) { if ( pSession->nSocket == pMsgHdr->nSocket ) { PostUserServerData( pSession, pBuffer, (INT)nBufSize, TRUE, TRUE, (TICKCOUNT)pMsgHdr->tickCount); } else { OutputMsg( rmWaning, "GM_DATA 会话(%d:%s)套接字不匹配,data Socket=%d,local socket=%d", pMsgHdr->wSessionIdx, pSession->sLoginCharName, pMsgHdr->nSocket,pSession->nSocket ); //SendCloseSession((SOCKET)pMsgHdr->nSocket); //如果套接字不匹配 //SendCloseSession( pSession, TRUE, enReasonAllSessionClose ); } } else { OutputMsg( rmWaning, "GM_DATA 会话(%d:%s,%d,%d)已关闭", pMsgHdr->wSessionIdx, pSession->sLoginCharName, (int)(pSession->boMarkToClose),(int)(pSession->boRemoteClosed)); //这种情况下再次向逻辑发送关闭连接 //SendCloseSession((SOCKET)pMsgHdr->nSocket); } } else OutputMsg( rmWaning, "GM_DATA 会话ID无效(%d)", pMsgHdr->wSessionIdx ); break; default: { GotError( __FUNCTION__, _T("无效的消息序列"), pMsgHdr->wIdent ); } break; } } VOID CRunDataProcesser::OnConnected() { Inherited::OnConnected(); m_llSendKeepAliveTime = 0; m_nCheckTimeCount = 0; m_llOccuTimeDiff = 0; OutputMsg(rmTip, _T("BackServer Connected")); } VOID CRunDataProcesser::OnClosed() { Inherited::OnClosed(); CloseAllSessions(true); } VOID CRunDataProcesser::OnError(int errorCode) { OutputError(errorCode, _T("BackServer Socket Error ")); } VOID CRunDataProcesser::OnDisconnected() { m_llSvrTimeDiff = 0; m_nCheckTimeCount = 0; m_llOccuTimeDiff = 0; OutputMsg(rmWaning, _T("BackServer Connection Closed")); } CRunDataProcesser::CRunDataProcesser(const int nMaxSessionCount) :Inherited() { m_nActiveUser = 0; m_boStoping = FALSE; m_boStarted = FALSE; m_DataProcessType = dp_Default; /* m_hPipe = INVALID_HANDLE_VALUE; strcpy( m_sPipeName, "\\\\.\\pipe\\default" ); sprintf( m_sGateName, "游戏网关%d", _getTickCount() % 100 ); */ m_hProcRecvThread = NULL; ZeroMemory( m_SendThreads, sizeof(m_SendThreads) ); m_nSendThreadCount = 2; m_nMaxSessionCount = nMaxSessionCount; // 默认值: 16384 m_Sessions = NULL; m_pSockProcesser = NULL; InitializeCriticalSection( &m_SessionLock ); if ( m_Sessions ) ZeroMemory( m_Sessions, sizeof(m_Sessions) ); InitializeCriticalSection( &m_RecvQueueLock ); m_pRecvAppendList = &m_RecvQueue[0]; m_pRecvProcList = &m_RecvQueue[1]; m_ServerBuf.lpBuffer= NULL; m_ServerBuf.nSize = 0; m_ServerBuf.nOffset = 0; m_nUserVerify = 1; m_dwProcessRecvSize = 0; m_boPrintC2SMsg = FALSE; m_boPrintS2CMsg = FALSE; m_llSvrTimeDiff = 0; m_nCheckTimeCount = 0; m_llOccuTimeDiff = 0; InitSendThreadData(); //m_DataPacker.SetNeedEncrypt(true); //需要加密 } CRunDataProcesser::~CRunDataProcesser() { Stop(); UninitSendThreadData(); DeleteCriticalSection( &m_RecvQueueLock ); DeleteCriticalSection( &m_SessionLock ); } VOID CRunDataProcesser::InitSessions() { int i; PRUNGATEUSERSESSION pSession; EnterCriticalSection( &m_SessionLock ); if ( !m_Sessions ) { m_Sessions = (PRUNGATEUSERSESSION)malloc(sizeof(m_Sessions[0]) * m_nMaxSessionCount); ZeroMemory( m_Sessions, sizeof(m_Sessions[0]) * m_nMaxSessionCount ); } pSession = m_Sessions; for ( i=0; inIndex = i; pSession->nSocket = INVALID_SOCKET; #ifdef WIN32 pSession->Overlapped.pUser = pSession; #endif pSession->nServerIdx = 0; pSession->btPacketIdx = 0; pSession->wPacketError = 0; pSession->nRecvPacketCount = 0; pSession->nSendPacketCount = 0; pSession->boMarkToClose = false; pSession->boRemoteClosed = false; pSession->boSendAvaliable = true; INIT_SESSION_SEND( pSession ); pSession++; } LeaveCriticalSection( &m_SessionLock ); } VOID CRunDataProcesser::UninitSessions() { int i; PRUNGATEUSERSESSION pSession; if ( !m_Sessions ) return; EnterCriticalSection( &m_SessionLock ); pSession = m_Sessions; for ( i=0; iRecvBuf.lpBuffer ) { free( pSession->RecvBuf.lpBuffer ); pSession->RecvBuf.lpBuffer = NULL; pSession->RecvBuf.nSize = pSession->RecvBuf.nOffset = 0; } if ( pSession->SendBuf.lpBuffer ) { free( pSession->SendBuf.lpBuffer ); pSession->SendBuf.lpBuffer = NULL; pSession->SendBuf.nSize = pSession->SendBuf.nOffset = 0; } UNINIT_SESSION_SEND( pSession ); pSession++; } free( m_Sessions ); m_Sessions = NULL; LeaveCriticalSection( &m_SessionLock ); } VOID CRunDataProcesser::FreeRecvBuffers() { INT_PTR i; void **pBuffers; EnterCriticalSection( &m_RecvQueueLock ); pBuffers = *m_pRecvAppendList; for ( i=m_pRecvAppendList->count()-1; i>-1; --i ) { free( pBuffers[i] ); } m_pRecvAppendList->clear(); pBuffers = *m_pRecvProcList; for ( i=m_pRecvProcList->count()-1; i>-1; --i ) { free( pBuffers[i] ); } m_pRecvProcList->clear(); LeaveCriticalSection( &m_RecvQueueLock ); } VOID CRunDataProcesser::FreeSendBuffers(PRUNDATASENDTHREAD pSendThread) { INT_PTR i; void **pBuffers; EnterCriticalSection( &pSendThread->SendQueueLock ); pBuffers = *pSendThread->pSendAppendList; for ( i=pSendThread->pSendAppendList->count()-1; i>-1; --i ) { free( pBuffers[i] ); } pSendThread->pSendAppendList->clear(); pBuffers = *pSendThread->pSendProcList; for ( i=pSendThread->pSendProcList->count()-1; i>-1; --i ) { free( pBuffers[i] ); } pSendThread->pSendProcList->clear(); LeaveCriticalSection( &pSendThread->SendQueueLock ); } /* BOOL CRunDataProcesser::OpenServerPipe() { int nErr; while ( TRUE ) { m_hPipe = CreateFile( m_sPipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL ); if ( m_hPipe != INVALID_HANDLE_VALUE ) return TRUE; nErr = GetLastError(); if ( nErr != ERROR_PIPE_BUSY ) { GotError( __FUNCTION__, "CreateFile", nErr ); break; } if ( !WaitNamedPipe( m_sPipeName, 10000 ) ) { nErr = GetLastError(); GotError( __FUNCTION__, "WaitNamedPipe", nErr ); break; } } return FALSE; } VOID CRunDataProcesser::CloseServerPipe() { if ( m_hPipe != INVALID_HANDLE_VALUE ) { CloseHandle( m_hPipe ); m_hPipe = INVALID_HANDLE_VALUE; } } VOID CRunDataProcesser::ServerPipeError() { if ( m_hPipe != INVALID_HANDLE_VALUE ) { CancelRemainSendSessionBuffers(); CloseHandle( m_hPipe ); m_hPipe = INVALID_HANDLE_VALUE; //CloseAllSessions 必须在CloseHandle之后调用,否则CloseAllSessions->SendServerMessage->ServerPipeError 造成栈溢出 CloseAllSessions( TRUE ); } } */ BOOL CRunDataProcesser::CopyWaitSendBuffers(PRUNDATASENDTHREAD pSendThread, BOOL boForceCopy) { PSENDCLIENTBUF pSendBuf, *ppBufers; CBaseList *pBufferList; PRUNGATEUSERSESSION pSession; INT_PTR nCount, nSize, nTotalSize, nAppendSize; TICKCOUNT dwMsgTick; if ( !boForceCopy ) boForceCopy = TryEnterCriticalSection( &pSendThread->SendQueueLock ); else EnterCriticalSection( &pSendThread->SendQueueLock ); if ( boForceCopy ) { pBufferList = pSendThread->pSendAppendList; pSendThread->pSendAppendList = pSendThread->pSendProcList; pSendThread->pSendProcList = pBufferList; LeaveCriticalSection( &pSendThread->SendQueueLock ); nCount = pBufferList->count(); if ( nCount > 0 ) { dwMsgTick = _getTickCount(); ppBufers = (PSENDCLIENTBUF*)(void**)(*pBufferList); nTotalSize = 0; nAppendSize = 0; do { pSendBuf = *ppBufers; ppBufers++; nCount--; pSession = pSendBuf->pSession; if ( pSession->nSocket != INVALID_SOCKET && !pSession->boMarkToClose && !pSession->boRemoteClosed ) { nSize = pSession->SendBuf.nOffset + pSendBuf->nBufferSize + 1; if ( pSession->SendBuf.nSize < nSize ) { nSize = (nSize / SESSION_DATAGROW_SIZE + 1) * SESSION_DATAGROW_SIZE; pSession->SendBuf.nSize = (INT)nSize; pSession->SendBuf.lpBuffer = (char*)realloc( pSession->SendBuf.lpBuffer, nSize ); } memcpy( &pSession->SendBuf.lpBuffer[pSession->SendBuf.nOffset], pSendBuf + 1, pSendBuf->nBufferSize ); pSession->SendBuf.nOffset += pSendBuf->nBufferSize; pSession->SendBuf.lpBuffer[pSession->SendBuf.nOffset] = 0; pSession->dwServerMsgTick = dwMsgTick; nAppendSize += pSendBuf->nBufferSize; } nTotalSize += pSendBuf->nBufferSize; free( pSendBuf ); } while ( nCount > 0 ); pBufferList->clear(); // 原子操作 InterlockedExchangeAdd( (LONG*)&m_dwWaitSendUserSize, (LONG)nAppendSize ); InterlockedExchangeAdd( (LONG*)&m_dwWaitSendQueueSize, -(INT)nTotalSize ); } } return boForceCopy; } VOID CRunDataProcesser::GetSessionLoginInfo(PRUNGATEUSERSESSION pSession, char *sBuffer, int nBufferSize) { } VOID CRunDataProcesser::GotError(LPCSTR sErrFn, LPCSTR sErrApi, int nErr) { OutputMsg( rmError, _T("%s Got Error %d on api \"%s\""), sErrFn, nErr, sErrApi ); } VOID CRunDataProcesser::InitSendThreadData() { int i; for ( i=0; i(); m_SendThreads[i].pSendProcList = new CBaseList(); } } VOID CRunDataProcesser::UninitSendThreadData() { int i; for ( i=0; iGetBindPort(); SendServerMessage(GM_GATEUSERINFO, 0, 0, 0, (char *)&gi, sizeof(GATEUSERINFO)); } VOID CRunDataProcesser::SendOpenSession(PRUNGATEUSERSESSION pSession) { char sRemoteAddr[32]; strcpy( sRemoteAddr, inet_ntoa( pSession->SockAddr.sin_addr ) ); SendServerMessage( GM_OPEN, pSession->nIndex, pSession->nSocket, 0, sRemoteAddr, (int)strlen(sRemoteAddr) + 1 ); OutputMsg(rmTip, _T("SendOpenSession: socket=%d sessionId=%d, remoteAddr=%s"), (int)pSession->nSocket, (int)pSession->nIndex, sRemoteAddr); } VOID CRunDataProcesser::SendCloseSession(PRUNGATEUSERSESSION pSession, BOOL boCloseOnServer, INT nReason) { PCLIENTRECVBUF pRecvBuf; int nSocket; if ( !pSession->boMarkToClose && pSession->nSocket != INVALID_SOCKET ) { OutputMsg( rmWaning, "关闭会话 socket=%d, sessionId=%d, serverId=%d,reasonId=%d,nVerifyIdx=%ld", (int)pSession->nSocket, (int)pSession->nIndex, (int)pSession->nServerIdx, nReason, pSession->nVerifyIdx ); pSession->boMarkToClose = true; nSocket = (int)pSession->nSocket; pSession->nSocket = INVALID_SOCKET; pSession->dwCloseTick = _getTickCount(); pSession->nVerifyIdx = 0; bool isInCommu =( pSession->nSessionSatus == enCommunication); //当前是否在通信状态 pSession->nSessionSatus = enSessionStatusIdle; //初始化状态 if (nSocket!=INVALID_SOCKET) closesocket( nSocket ); //如果需要向服务器发送关闭用户的消息则将消息添加到队列 //并且需要通信状态了,否则不需要发包,说明还没有通过验证 if ( boCloseOnServer && isInCommu ) { SendServerMessage( GM_CLOSE, 0, nSocket, 0, NULL, 0 ); } m_nActiveUser--; } } VOID CRunDataProcesser::SendKeepAliveAck(PRUNGATEUSERSESSION pSession, const char *pBuffer, SIZE_T nBufSize) { SendServerMessage(GM_APPKEEPALIVEACK, pSession->nIndex, pSession->nSocket, pSession->nServerIdx, (char *)pBuffer, (int)nBufSize); } VOID CRunDataProcesser::CloseAllSessions(BOOL boForceClose) { int i; TICKCOUNT dwCurTick; PRUNGATEUSERSESSION pSession; if ( !m_Sessions ) return; pSession = m_Sessions; EnterCriticalSection( &m_SessionLock ); EnterCriticalSection( &m_RecvQueueLock ); for ( i=0; inSocket != INVALID_SOCKET ) { if ( boForceClose ) { OutputMsg(rmTip,_T("CRunDataProcesser::CloseAllSessions close socket=%d"),(int)pSession->nSocket); SendCloseSession( pSession, TRUE, enReasonAllSessionClose ); //closesocket( pSession->nSocket ); pSession->boMarkToClose = true; pSession->boRemoteClosed = true; pSession->dwCloseTick = 0; pSession->nSocket = INVALID_SOCKET; pSession->nVerifyIdx = 0; m_nActiveUser--; if ( pSession->RecvBuf.lpBuffer ) { free( pSession->RecvBuf.lpBuffer ); pSession->RecvBuf.lpBuffer = NULL; } pSession->RecvBuf.nSize = pSession->RecvBuf.nOffset = 0; if ( pSession->SendBuf.lpBuffer ) { free( pSession->SendBuf.lpBuffer ); pSession->SendBuf.lpBuffer = NULL; } pSession->SendBuf.nSize = pSession->SendBuf.nOffset = 0; } else SendCloseSession( pSession, TRUE, enReasonAllSessionClose ); } pSession++; } for ( i=0; i *pBufferList; INT_PTR i, nCount, nTotalSize; nTotalSize = 0; for ( i=0; icount(); if ( nCount ) { ppBufers = (PSENDCLIENTBUF*)(void**)(*pBufferList); do { pSendBuf = *ppBufers; ppBufers++; nCount--; nTotalSize += pSendBuf->nBufferSize; free( pSendBuf ); } while ( nCount > 0 ); pBufferList->clear(); } pBufferList = m_SendThreads[i].pSendAppendList; nCount = pBufferList->count(); if ( nCount ) { ppBufers = (PSENDCLIENTBUF*)(void**)(*pBufferList); do { pSendBuf = *ppBufers; ppBufers++; nCount--; nTotalSize += pSendBuf->nBufferSize; free( pSendBuf ); } while ( nCount > 0 ); pBufferList->clear(); } LeaveCriticalSection( &m_SendThreads[i].SendQueueLock ); } InterlockedExchangeAdd( (LONG*)&m_dwWaitSendQueueSize, -(INT)nTotalSize ); } BOOL CRunDataProcesser::CheckCloseSessions(BOOL boForceCheck) { static const DWORD dwCloseIdleSessionLong = 10 * 60 * 1000; int i, boResult; TICKCOUNT dwCurTick; PRUNGATEUSERSESSION pSession; if ( boForceCheck ) { EnterCriticalSection( &m_SessionLock ); boResult = TRUE; } else boResult = TryEnterCriticalSection( &m_SessionLock ); if ( boResult ) { dwCurTick = _getTickCount(); pSession = m_Sessions - 1; for ( i=0; iboMarkToClose || pSession->boRemoteClosed ) { //加上pSession->dwCloseTick非0判断,防止内存错误 //可能的原因是标记pSession->boMarkToClose或pSession->boRemoteClosed为true的线程尚未来得及 //给pSession->dwCloseTick赋值,而此线程恰好已经执行到此处对pSession的资源进行释放,从而 //造成内存错误。 if ( pSession->dwCloseTick && dwCurTick - pSession->dwCloseTick >= 10 * 1000 ) { if(pSession->nSocket != INVALID_SOCKET) { OutputMsg( rmWaning, "Socket%d 标记为删除",(int)pSession->nSocket ); } LOCK_SESSION_SEND( pSession ); pSession->nSocket = INVALID_SOCKET; pSession->nVerifyIdx = 0; if ( pSession->RecvBuf.lpBuffer ) { free( pSession->RecvBuf.lpBuffer ); pSession->RecvBuf.lpBuffer = NULL; } pSession->RecvBuf.nSize = pSession->RecvBuf.nOffset = 0; if ( pSession->SendBuf.lpBuffer ) { free( pSession->SendBuf.lpBuffer ); pSession->SendBuf.lpBuffer = NULL; } pSession->SendBuf.nSize = 0;//SendBuf.nOffset值由发送线程维护 pSession->boMarkToClose = false; pSession->boRemoteClosed = false; pSession->dwCloseTick = 0; UNLOCK_SESSION_SEND( pSession ); } } else if ( pSession->nSocket != INVALID_SOCKET ) { if (dwCurTick - pSession->dwClientMsgTick >= dwCloseIdleSessionLong) { OutputMsg( rmWaning, "客户端Idle,dwCurTick=%ld,dwClientMsgTick=%ld",(long long)dwCurTick, (long)pSession->dwClientMsgTick); SendCloseSession( pSession, TRUE, enReasonIdle ); } if(dwCurTick - pSession->dwServerMsgTick >= dwCloseIdleSessionLong) { //OutputMsg( rmWaning, "服务器较长时间处于非活动状态的会话,关闭会话" ); //OutputMsg( rmWaning, "服务器端idle,dwCurTick=%I64d,dwClientMsgTick=%I64d",(long long)dwCurTick, (long long)pSession->dwServerMsgTick); //SendCloseSession( pSession, TRUE, enReasonIdle ); } } } LeaveCriticalSection( &m_SessionLock ); } return boResult; } VOID CRunDataProcesser::CheckSendSessionBuffers(PRUNDATASENDTHREAD pSendThread) { DECLARE_FUN_TIME_PROF(); static char sSendCheckBuf[RUNGATE_ONCESENDUSE_LIMIT]; int nErr, nRemainSize; char *pBuffer; PRUNGATEUSERSESSION pSession = &m_Sessions[pSendThread->nThreadIdx]; pSendThread->boSendEWouldBlock = false; pSendThread->boSendFewBuffer = false; for ( ;pSession <= &m_Sessions[m_nMaxSessionCount-1]; pSession += m_nSendThreadCount ) { if ( pSession->nSocket != INVALID_SOCKET && !pSession->boMarkToClose && !pSession->boRemoteClosed ) { if ( !pSession->boSendAvaliable ) { if ( _getTickCount() >= pSession->dwSendTimeOut ) { pSession->boSendAvaliable = true; pSession->dwSendTimeOut = 0; } else continue; } if ( TRYLOCK_SESSION_SEND( pSession ) ) { nRemainSize = pSession->SendBuf.nOffset; if ( nRemainSize > 4096 * 1024 ) { SendCloseSession( pSession, TRUE, enReasonSenderBuffLarge ); nRemainSize = 0; OutputMsg( rmWaning, "关闭了一个发送数据队列大于4MB的连接。" ); } if ( nRemainSize ) { pBuffer = pSession->SendBuf.lpBuffer; if ( nRemainSize >= MAXINT )//不让它执行这段代码 { sSendCheckBuf[0] = '*'; memcpy( &sSendCheckBuf[1], pBuffer, RUNGATE_ONCESENDUSE_LIMIT -1 ); nErr = ::send( pSession->nSocket, sSendCheckBuf, RUNGATE_ONCESENDUSE_LIMIT, 0 ); if ( nErr > 0 ) { if ( nErr != RUNGATE_ONCESENDUSE_LIMIT ) pSendThread->boSendFewBuffer = true; InterlockedExchangeAdd( (LONG*)&m_dwWaitSendUserSize, -(nErr - 1) ); InterlockedExchangeAdd( (LONG*)&m_dwSendUserSize, nErr ); nRemainSize -= nErr - 1; memmove( pBuffer, &pBuffer[nErr - 1], nRemainSize ); pSession->SendBuf.nOffset = nRemainSize; pBuffer[nRemainSize] = 0; pSession->nSendPacketCount++; } else if ( !nErr || WSAGetLastError() != WSAEWOULDBLOCK ) { InterlockedExchangeAdd( (LONG*)&m_dwWaitSendUserSize, -pSession->SendBuf.nOffset ); pSession->boRemoteClosed = true; pSession->SendBuf.nOffset = 0; SendCloseSession( pSession, TRUE, enReasonSocketError ); } else { pSession->boSendAvaliable = false; pSession->dwSendTimeOut = _getTickCount() + RUNGATE_SENDCHECK_TIMEOUT; pSendThread->boSendEWouldBlock = true; } } else { TICKCOUNT nCurTick = _getTickCount(); if (nCurTick < pSession->nLastSendPacketTime) pSession->nLastSendPacketTime = 0; if (nCurTick - pSession->nLastSendPacketTime >= 15) { pSession->nLastSendPacketTime = nCurTick; nErr = ::send( pSession->nSocket, pBuffer, nRemainSize, 0 ); if ( nErr > 0 ) { pSession->nSendPacketCount++; InterlockedExchangeAdd( (LONG*)&m_dwWaitSendUserSize, -nErr ); InterlockedExchangeAdd( (LONG*)&m_dwSendUserSize, nErr ); if ( nErr < nRemainSize ) { pSendThread->boSendFewBuffer = true; memmove( pBuffer, &pBuffer[nErr], nRemainSize - nErr ); nRemainSize -= nErr; pBuffer[nRemainSize] = 0; pSession->SendBuf.nOffset = nRemainSize; pSession->nTimeStampOffset = nRemainSize; } else { pBuffer[0] = 0; pSession->SendBuf.nOffset = 0; pSession->nTimeStampOffset = 0; } #ifdef _DEBUG char * pIp = inet_ntoa(pSession->SockAddr.sin_addr); OutputMsg( rmTip, "[%s]Idx=%d: 发到客户端, 已发长度%d, 剩余待发%d;", pIp, pSession->nVerifyIdx, nErr, pSession->SendBuf.nOffset); #endif } else { int nErrorId = WSAGetLastError(); if ( !nErr || nErrorId != WSAEWOULDBLOCK ) { OutputMsg(rmWaning,"Socket =%d,send fail, errorid=%d ",(int)pSession->nSocket,nErrorId); InterlockedExchangeAdd( (LONG*)&m_dwWaitSendUserSize, -nRemainSize ); InterlockedExchangeAdd( (LONG*)&m_dwSendUserSize, nRemainSize ); pBuffer[0] = 0; pSession->SendBuf.nOffset = 0; pSession->boRemoteClosed = true; SendCloseSession( pSession, TRUE, enReasonSenderBuffLarge ); } else { pSession->boSendAvaliable = false; pSession->dwSendTimeOut = _getTickCount() + RUNGATE_SENDCHECK_TIMEOUT; pSendThread->boSendEWouldBlock = true; } } } } } UNLOCK_SESSION_SEND( pSession ); } } else { //会话关闭后减少待发送数据统计值 if ( nRemainSize = pSession->SendBuf.nOffset ) { InterlockedExchangeAdd( (LONG*)&m_dwWaitSendUserSize, -nRemainSize ); pSession->SendBuf.nOffset = 0; } } } } //发送数据到服务器 VOID CRunDataProcesser::SendServerMessage(int nIdent, int nSessionIdx, SOCKET nSocket, int nServerIdx, char *pBuffer, int nBufSize) { if ( !connected() ) return; PutMessage(nIdent, nSessionIdx, nSocket, nServerIdx, m_llSvrTimeDiff, pBuffer, nBufSize); } /* * 解包数据 * param[] pInBuff 输入的数据包 * param[] nInSize 输入的数据包的长度 * param[] pOutBuff 输出的数据包指针 * param[] nOutSize 输出的数据包的长度 * param[] nInProcessSize 输入的数据包处理了的长度,如果大于0,那么前面的这个字节的数据包可以丢弃了 * param[] nOutProcessSize 处理好的数据长度,处理好的数据放在pOutBuff里 * ret 如果进行了数据处理返回true,否则返回false。数据处理包括发现前面有无效数字,拷贝了一个完整的数据包,丢弃一些字节等 */ static bool DataUnpack(PRUNGATEUSERSESSION pSession, char* pInBuff, SIZE_T nInSize, char* pOutBuff, SIZE_T nOutSize, SIZE_T& nInProcessSize, SIZE_T& nOutProcessSize) { nInProcessSize =0; nOutProcessSize =0; SIZE_T nHeaderSize = sizeof(DATAHEADER); if (nInSize < nHeaderSize ) return false; //输入的数据不够 if (NULL == pInBuff || NULL == pOutBuff) return false; bool tagFlag =false; //tag的寻找标志 SIZE_T i =0; WORD * pTagPos =NULL; for ( ;i < nInSize -1; i++) { pTagPos = (WORD *)(pInBuff + i); if(*pTagPos == pSession->nKey) //如果找到了tag { tagFlag = true; //找到了头 break; } } if (tagFlag ==false ) { i ++; } nInProcessSize = i; //前面的几个字节,如果不是头,将说明是垃圾数据,将被干掉 SIZE_T nLeftCount = nInSize - i; //还有多少个字节再后面 //剩下的数据不够头,或者没有找到头 if (tagFlag ==false || nLeftCount < nHeaderSize ) { if (nInProcessSize >0) { return true; } else { return false; } } DATAHEADER data; //把数据拷贝一份过来 memcpy( (void *)&data,(void*) (pInBuff + i),nHeaderSize ); //拷贝一份 PDATAHEADER pHeader = &data; //把后面的转换为数据头的指针 SIZE_T nTotalPackSize = pHeader->len + nHeaderSize ; //一个完整的数据包的需要的长度 if ( nTotalPackSize > nLeftCount ) return false; //数据不齐全,没有len个字节发送过来 else { //拷贝数据 memcpy(pOutBuff,(void *)(pInBuff + i ),nTotalPackSize) ; nInProcessSize = i + nTotalPackSize; nOutProcessSize = nTotalPackSize; } return true; } //收到用户的数据包 VOID CRunDataProcesser::ProcessUserRecvPacket(PRUNGATEUSERSESSION pSession, char *pBuffer, int nBufferSize) { DECLARE_FUN_TIME_PROF(); InterlockedExchangeAdd( (LONG*)&m_dwProcessRecvSize, nBufferSize ); //session中已缓存的数据(剩下待处理的数据) int nLeftDataSize = pSession->RecvBuf.nOffset + nBufferSize + 1; if ( pSession->RecvBuf.nSize < nLeftDataSize ) { pSession->RecvBuf.nSize = (nLeftDataSize / SESSION_DATAGROW_SIZE + 1) * SESSION_DATAGROW_SIZE; pSession->RecvBuf.lpBuffer = (char*)realloc( pSession->RecvBuf.lpBuffer, pSession->RecvBuf.nSize ); } nLeftDataSize--; //将数据拷贝过来 char *pDataBuffer; pDataBuffer = pSession->RecvBuf.lpBuffer; memcpy( &pDataBuffer[pSession->RecvBuf.nOffset], pBuffer, nBufferSize ); pSession->RecvBuf.nOffset = nLeftDataSize; pDataBuffer[nLeftDataSize] = 0; //如果剩余数据超过峰值则丢弃 if ( pSession->RecvBuf.nOffset >= SESSION_MAX_RECVPROC_SIZE ) { pSession->RecvBuf.nOffset = 0; SendCloseSession( pSession, TRUE, enReasonLargePackLeft ); return; } //处理Session的buffer char pDataProcBuf[MAX_SEND_BUFF_SIZE]; #ifdef _DEBUG memset(pDataProcBuf, 0, MAX_SEND_BUFF_SIZE); #endif while ( nLeftDataSize > 0 ) { if ( pSession->wPacketError >= SESSION_PACKETERR_MAX ) { nLeftDataSize = 0; SendCloseSession( pSession, TRUE, enReasonRecvLargerPack ); OutputMsg( rmWaning, "wPacketError=%d,超出了",pSession->wPacketError); break; } if ( pSession->boMarkToClose || pSession->boRemoteClosed ) { OutputMsg( rmTip, "远程关闭,不处理数据"); break; } SIZE_T nBuffSize = pSession->RecvBuf.nOffset ; //刚连接上来 if (enConn == pSession->nSessionSatus) { SendOpenSession(pSession);//发送到LogicServer新增连接 pSession->nKey = (unsigned short)wrand(INT_MAX); PostUserServerData(pSession, (char *)&pSession->nKey, 2); pSession->nSessionSatus = enCommunication; } //正常通讯,将输出的数据要传递到LogicServer else if (pSession->nSessionSatus == enCommunication) { SIZE_T nInprocessSize =0 ,nOutProcessSize =0; // 数据解包处理 if (DataUnpack(pSession, pDataBuffer, nLeftDataSize, pDataProcBuf, MAX_SEND_BUFF_SIZE, nInprocessSize, nOutProcessSize)) { // 调整已处理过的字节 if (nInprocessSize > 0) { nLeftDataSize -= (INT)nInprocessSize; if (nLeftDataSize < 0) { nLeftDataSize = 0; } else { pDataBuffer = (char *)(pDataBuffer + nInprocessSize); } } //检查服务端key if (nOutProcessSize >= 2) { unsigned short tag = *((unsigned short*)pDataProcBuf); if(tag != pSession->nKey) { SendCloseSession(pSession, TRUE, 2); return; } //截去头部 char* pOutData = (char*)pDataProcBuf + sizeof(DATAHEADER); nOutProcessSize -= sizeof(DATAHEADER); //把数据发到服务器 SendServerMessage(GM_DATA, pSession->nIndex, pSession->nSocket, pSession->nServerIdx, pOutData, (INT)nOutProcessSize); } } else { OutputMsg( rmTip, "消息长度不够,等待下一次组包"); break; } } } //修正Session的buffer if (pSession->RecvBuf.lpBuffer != NULL) { if ( nLeftDataSize > 0 ) { if ( pDataBuffer != pSession->RecvBuf.lpBuffer ) { memmove( pSession->RecvBuf.lpBuffer, &pSession->RecvBuf.lpBuffer[pSession->RecvBuf.nOffset - nLeftDataSize], nLeftDataSize ); pSession->RecvBuf.lpBuffer[nLeftDataSize] = 0; pSession->RecvBuf.nOffset = nLeftDataSize; } } else { pSession->RecvBuf.lpBuffer[0] = 0; pSession->RecvBuf.nOffset = 0; } } } int CRunDataProcesser::s_nIgnoreDataPacket = 0; VOID CRunDataProcesser::PostUserServerData(PRUNGATEUSERSESSION pSession, const char *pBuffer, int nBufferSize, BOOL boWriteWsHdr, BOOL boWriteProtoHdr, TICKCOUNT nSendTime) { DECLARE_FUN_TIME_PROF(); char *pDataPtr; PRUNDATASENDTHREAD pSendThread; PSENDCLIENTBUF pSendBuf; PDATAHEADER pProtoHdr; static char sPrintS2CBuffer[81920]; pSendThread = &m_SendThreads[pSession->nIndex % m_nSendThreadCount]; pSendBuf = (PSENDCLIENTBUF)malloc( nBufferSize + sizeof(*pSendBuf) + 4 + sizeof(*pProtoHdr) + 16); pSendBuf->pSession = pSession; pDataPtr = (char*)(pSendBuf + 1); if ( boWriteProtoHdr ) { pProtoHdr = (PDATAHEADER)pDataPtr; pProtoHdr->tag = pSession->nKey; pProtoHdr->len = nBufferSize; pDataPtr += sizeof(*pProtoHdr); } memcpy( pDataPtr, pBuffer, nBufferSize ); if ( boWriteProtoHdr ) nBufferSize += sizeof(*pProtoHdr); pSendBuf->nBufferSize = nBufferSize; InterlockedExchangeAdd( (LONG*)&m_dwWaitSendQueueSize, nBufferSize ); EnterCriticalSection( &pSendThread->SendQueueLock ); pSendThread->pSendAppendList->add( pSendBuf ); LeaveCriticalSection( &pSendThread->SendQueueLock ); } INT CRunDataProcesser::GetActiveUserCount() { return m_nActiveUser; } VOID CRunDataProcesser::SetName(LPCSTR sName) { ZeroMemory( m_sGateName, sizeof(m_sGateName) ); strncpy( m_sGateName, sName, __min(sizeof(m_sGateName)-1, strlen(sName)) ); SetClientName(sName); } /* VOID CRunDataProcesser::SetPipeName(LPCSTR sPipeName) { ZeroMemory( m_sPipeName, sizeof(m_sPipeName) ); strncpy( m_sPipeName, sPipeName, __min(sizeof(m_sPipeName)-1, strlen(sPipeName)) ); } */ INT CRunDataProcesser::GetSendThreadCount() { return m_nSendThreadCount; } VOID CRunDataProcesser::SetSendThreadCount(INT ThreadCount) { if ( !m_boStarted && ThreadCount > 0 && ThreadCount <= RUNDATA_MAX_SENDTHREAD ) { m_nSendThreadCount = ThreadCount; } } DATAPROCESSERTYPE CRunDataProcesser::GetDataProcessType() { return m_DataProcessType; } VOID CRunDataProcesser::SetDataProcessType(DATAPROCESSERTYPE Type) { m_DataProcessType = Type; } VOID CRunDataProcesser::SetRunSockProcesser(CRunSockProcesser* pSockProcesser) { m_pSockProcesser = pSockProcesser; } INT CRunDataProcesser::GetMaxSessionCount() { return m_nMaxSessionCount; } PRUNDATASENDTHREAD CRunDataProcesser::GetSendThreadInfo(INT ThreadIdx) { if ( ThreadIdx >= 0 && ThreadIdx < RUNDATA_MAX_SENDTHREAD ) { if ( m_SendThreads[ThreadIdx].hThread ) return &m_SendThreads[ThreadIdx]; } return NULL; } PRUNGATEUSERSESSION CRunDataProcesser::GetFirstSession() { return m_Sessions; } VOID CRunDataProcesser::SetPrintC2SMessage(const BOOL boPrint) { m_boPrintC2SMsg = boPrint; } VOID CRunDataProcesser::SetPrintS2CMessage(const BOOL boPrint) { m_boPrintS2CMsg = boPrint; } BOOL CRunDataProcesser::Startup() { int i; m_boStoping = FALSE; m_dwWaitSendUserSize = 0; m_dwWaitSendQueueSize = 0; m_dwLastProcUsrMsgTime = 0; m_dwLastProcSrvMsgTime = 0; m_dwLastRecvSrvMsgTime = 0; m_dwRecvSeverSize = 0; m_dwSendUserSize = 0; m_dwProcSrvThreadSleep = 0; m_dwSendQueueSize = 0; //初始化会话队列 InitSessions(); //创建用户数据处理线程 #ifdef _MSC_VER m_hProcRecvThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)RecvDataProcessRoutine, this, 0, NULL ); if ( !m_hProcRecvThread ) { GotError( __FUNCTION__, _T("CreateThread"), GetLastError() ); return FALSE; } #else if (pthread_create(&m_hProcRecvThread, NULL, RecvDataProcessRoutine, this)) { return FALSE; } #endif //创建用户数据发送线程 for ( i=0; iGetName()); nLine++; ChangeConsoleLine( nLine, 0, "活动连接数:%d \n", pRunData->GetActiveUserCount() ); nLine++; ChangeConsoleLine( nLine, 0, "接收用户数据: %dB 发送用户数据: %dKB 待发用户数据: %dKB 待发用户队列: %dKB \n", pRunData->m_dwProcessRecvSize, pRunData->m_dwSendUserSize / 1024, pRunData->m_dwWaitSendUserSize / 1024, pRunData->m_dwSendQueueSize / 1024 ); nLine++; ChangeConsoleLine( nLine, 0, "接收引擎数据: %dKB 接收数据时间: %d毫秒 引擎数据处理: %d毫秒 用户数据处理: %d毫秒 \n", pRunData->m_dwRecvSeverSize / 1024, pRunData->m_dwLastRecvSrvMsgTime, pRunData->m_dwLastProcSrvMsgTime, pRunData->m_dwLastProcUsrMsgTime ); nLine++; for ( i=0; iGetSendThreadInfo( i ); if ( !pSendThread ) continue; ChangeConsoleLine( nLine, 0, "发送线程%d[数据处理: %d毫秒 休眠时间: %d毫秒 标志:%d/%d] \n", i, pSendThread->dwProcTick, pSendThread->dwSleepTick, pSendThread->boSendEWouldBlock, pSendThread->boSendFewBuffer ); nLine++; InterlockedExchange( (LONG*)&pSendThread->dwProcTick, 0 ); InterlockedExchange( (LONG*)&pSendThread->dwSleepTick, 0 ); } ChangeConsoleLine( nLine, 0, "服务器数据处理线程休眠: %d毫秒\n", pRunData->m_dwProcSrvThreadSleep ); nLine++; ChangeConsoleLine( nLine, 0, "----------------------------------------------------------------\n" ); nLine++; pRunData->Dump(); InterlockedExchange( (LONG*)&pRunData->m_dwProcessRecvSize, 0 ); InterlockedExchange( (LONG*)&pRunData->m_dwSendUserSize, 0 ); InterlockedExchange( (LONG*)&pRunData->m_dwRecvSeverSize, 0 ); } VOID CRunDataProcesser::Stop() { int i; m_boStoping = TRUE; Inherited::Stop(); CloseThread( m_hProcRecvThread ); for ( i=0; inSocket == INVALID_SOCKET && !pSession->boMarkToClose && !pSession->boRemoteClosed && !pSession->dwCloseTick && pSession->nSessionSatus ==enSessionStatusIdle) { pNewSession = pSession; pNewSession->SendBuf.nOffset = 0; pNewSession->dwCloseTick = 0; pNewSession->boMarkToClose = false; pNewSession->boRemoteClosed = false; pNewSession->nSessionSatus = enConn; break; } pSession++; } LeaveCriticalSection( &m_SessionLock ); if ( pNewSession ) { pNewSession->SockAddr = RemoteAddr; pNewSession->nServerIdx = 0; pNewSession->btPacketIdx = 0; pNewSession->wPacketError = 0; pNewSession->nRecvPacketCount=0; pNewSession->nSendPacketCount=0; pNewSession->boMarkToClose = false; pNewSession->boRemoteClosed = false; pNewSession->boSendAvaliable= true; pNewSession->dwSendTimeOut = 0; pNewSession->dwCloseTick = 0; pNewSession->dwConnectTick = _getTickCount(); pNewSession->dwClientMsgTick= pNewSession->dwConnectTick; pNewSession->dwServerMsgTick= pNewSession->dwConnectTick; pNewSession->nVerifyIdx = InterlockedIncrement( (unsigned long long*)&m_nUserVerify ); pNewSession->sLoginAccount[0] = 0; pNewSession->sLoginCharName[0]= 0; //pNewSession->nSessionId = 0; if ( !pNewSession->RecvBuf.lpBuffer ) { pNewSession->RecvBuf.nSize = SESSION_RECV_BUFSIZE ; pNewSession->RecvBuf.lpBuffer = (char*)malloc( pNewSession->RecvBuf.nSize ); } pNewSession->RecvBuf.nOffset = 0; #ifdef WIN32 pNewSession->Overlapped.WSABuf.buf = pNewSession->sRecvBuf; pNewSession->Overlapped.WSABuf.len = sizeof(pNewSession->sRecvBuf) - 1; #endif pNewSession->sRecvBuf[sizeof(pNewSession->sRecvBuf)] = 0; if ( !pNewSession->SendBuf.lpBuffer ) { pNewSession->SendBuf.nSize = SESSION_SEND_BUFSIZE ; pNewSession->SendBuf.lpBuffer = (char*)malloc( pNewSession->SendBuf.nSize ); } pNewSession->SendBuf.nOffset = 0; //最后设置会话的nSocket成员数据, //以防止其他线程通过nSocket != INVALID_SOCKET判断后对一个尚为初始化完毕的会话进行操作! pNewSession->nSocket = nSocket; pNewSession->nSessionSatus = enConn; //开始处于连接状态 char * pIp = inet_ntoa(RemoteAddr.sin_addr); OutputMsg( rmTip, "[%s]接入新的socket=%d 完毕,nVerifyIdx=%ld",pIp, (int)nSocket,pNewSession->nVerifyIdx); m_nActiveUser++; //增加活动用户计数 } return pNewSession; } static bool gFindHttpParam(const char * param, const char * buf) { while (*param == *buf) { if (*(param + 1) == '\0') return true; ++param; ++buf; } return false; } VOID CRunDataProcesser::AddRecvBuf(PRUNGATEUSERSESSION pSession,unsigned long long nVerify, char *pBuffer, int BufferSize) { PCLIENTRECVBUF pRecvBuf; char *pData; if ( pSession->nSocket == INVALID_SOCKET || pSession->boMarkToClose || pSession->boRemoteClosed || !nVerify || pSession->nVerifyIdx != nVerify ) return; pRecvBuf = (PCLIENTRECVBUF)malloc( sizeof(*pRecvBuf) + BufferSize + 1 ); pRecvBuf->pSession = pSession; pRecvBuf->nVerify = nVerify; pRecvBuf->nBufferSize = BufferSize; pData = (char*)(pRecvBuf + 1); memcpy( pData, pBuffer, BufferSize ); pData[BufferSize] = 0; EnterCriticalSection( &m_RecvQueueLock ); m_pRecvAppendList->add( pRecvBuf ); LeaveCriticalSection( &m_RecvQueueLock ); }