// main processing loop void MainLoop () { // loop processing input, output, events do { // We will go through this loop roughly every COMMS_WAIT_SEC/COMMS_WAIT_USEC // seconds (at present 0.5 seconds). PeriodicUpdates (); // do things that don't rely on player input // delete players who have closed their comms - have to do it outside other loops to avoid // access violations (iterating loops that have had items removed) RemoveInactivePlayers (); // get ready for "select" function ... FD_ZERO (&in_set); FD_ZERO (&out_set); FD_ZERO (&exc_set); // add our control socket (for new connections) FD_SET (iControl, &in_set); // set bits in in_set, out_set etc. for each connected player int iMaxdesc = for_each (playerlist.begin (), playerlist.end (), setUpDescriptors (iControl)).GetMax (); // set up timeout interval struct timeval timeout; timeout.tv_sec = COMMS_WAIT_SEC; // seconds timeout.tv_usec = COMMS_WAIT_USEC; // + 1000th. of second // check for activity, timeout after 'timeout' seconds if (select (iMaxdesc + 1, &in_set, &out_set, &exc_set, &timeout) > 0) { // New connection on control port? if (FD_ISSET (iControl, &in_set)) ProcessNewConnection (); // handle all player input/output for_each (playerlist.begin (), playerlist.end (), processDescriptors ()); } // end of something happened } while (!bStopNow); // end of looping processing input } // end of MainLoop
void KPlayerServer::ProcessNetwork(void) { int nRetCode = false; while (true) { int nEventCount = 0; KG_SOCKET_EVENT* pSocketEvent = NULL; KG_SOCKET_EVENT* pSocketEventEnd = NULL; nRetCode = m_SocketServerAcceptor.Wait(m_nSocketEventCount, m_pSocketEventArray, &nEventCount); KGLOG_PROCESS_ERROR(nRetCode); if (nEventCount == 0) break; pSocketEventEnd = m_pSocketEventArray + nEventCount; for (pSocketEvent = m_pSocketEventArray; pSocketEvent < pSocketEventEnd; pSocketEvent++) { // Process new connection accept // KG_SOCKET_EVENT_ACCEPT event must be processed before any other event, // because Maybe uEventFlag = KG_SOCKET_EVENT_ACCEPT | KG_SOCKET_EVENT_IN. if (pSocketEvent->uEventFlag & KG_SOCKET_EVENT_ACCEPT) { ProcessNewConnection(pSocketEvent->piSocket); KG_COM_RELEASE(pSocketEvent->piSocket); continue; } if (!(pSocketEvent->uEventFlag & KG_SOCKET_EVENT_IN)) { KGLogPrintf(KGLOG_DEBUG, "Unexpected socket event: %u", pSocketEvent->uEventFlag); KG_COM_RELEASE(pSocketEvent->piSocket); continue; } ProcessPackage(pSocketEvent->piSocket); KG_COM_RELEASE(pSocketEvent->piSocket); } } Exit0: return; }
tERROR CProxySessionManager::ProxyMain(SOCKET Server, SOCKET Server_v6, SOCKET CrService, SOCKET CrService_v6 ) { int RetVal = 0; DWORD dwCount; CProxySession* Session; fd_set fds; TIMEVAL Timeout = { 1, 0 }; // 1 second Timeout SOCKET MySock = INVALID_SOCKET; while(true) { FD_ZERO(&fds); if ( Server != INVALID_SOCKET ) FD_SET(Server, &fds); if ( Server_v6 != INVALID_SOCKET ) FD_SET(Server_v6, &fds); if ( CrService != INVALID_SOCKET ) FD_SET(CrService, &fds); if ( CrService_v6 != INVALID_SOCKET ) FD_SET(CrService_v6, &fds); // ѕолучаем набор дескрипторов, у которых мы ожидаем какой-либо активности. dwCount = GetDescriptors( &fds ); CKAHCR::SetWatchdogTimeout( ( SESSION_LIST_REFRESH_TIMEOUT / 1000 ) * 2); // выгрызаем из набора дескриптор с событием. RetVal = select( 0, &fds, NULL, NULL, &Timeout ); // KLSTD_TRACE1( KLMC_TRACELEVEL, "CProxySessionManager::ProxyMain : select return %d\n", RetVal ); CKAHCR::SetWatchdogTimeout( ( SESSION_LIST_REFRESH_TIMEOUT / 1000 ) * 2); // проверка на выгрузку if ( WAIT_OBJECT_0 == WaitForSingleObject( m_hStopEvent, 0 )) { // global stop event KLSTD_TRACE0( KLMC_TRACELEVEL, "CProxySessionManager::ProxyMain => Received m_hStopEvent\n" ); break; } if ( WAIT_OBJECT_0 == WaitForSingleObject( m_hRequestSessionStop, 0 )) { KLSTD_TRACE0( KLMC_TRACELEVEL, "CProxySessionManager::ProxyMain => Received m_hRequestSessionStop\n" ); ProcessPseudoStop(); continue; } if ( RetVal == SOCKET_ERROR ) { KLSTD_TRACE2( KLMC_TRACELEVEL, "CProxySessionManager::ProxyMain => select returned %d. err = %d\n", RetVal, WSAGetLastError() ); break; } // обработка новых подключений к слушающим сокетам if ( FD_ISSET(Server, &fds) ) { FD_CLR( Server, &fds ); ProcessNewConnection( Server ); continue; } if ( FD_ISSET(Server_v6, &fds) ) { FD_CLR( Server_v6, &fds ); ProcessNewConnection( Server_v6 ); continue; } if ( FD_ISSET(CrService, &fds) ) { FD_CLR( CrService, &fds ); ProcessNewConnection( CrService ); continue; } if ( FD_ISSET(CrService_v6, &fds) ) { FD_CLR( CrService_v6, &fds ); ProcessNewConnection( CrService_v6 ); continue; } // обработка "сп¤щих" клиентов. Session = GetClient( &fds ); if ( Session ) { if ( !Session->StartClient() ) { KLSTD_TRACE1( KLMC_TRACELEVEL, "CProxySessionManager::ProxyMain: Unable To restart Client %x \n", Session ); Sleep( 1000 ); AddClient( Session ); } } else { // timeout m_SessionList.erase( remove_if( m_SessionList.begin(), m_SessionList.end(),CDoneSession()), m_SessionList.end()); } } if ( Server != INVALID_SOCKET ) closesocket( Server ); if ( Server_v6 != INVALID_SOCKET ) closesocket( Server_v6 ); if ( CrService != INVALID_SOCKET ) closesocket( CrService ); if ( CrService_v6 != INVALID_SOCKET ) closesocket( CrService_v6 ); return errOK; }