DWORD WINAPI PortalMCThreadFn( LPVOID p ) { CUtlVector<char> data; data.SetSize( portalbytes + 128 ); DWORD waitTime = 0; while ( WaitForSingleObject( g_MCThreadExitEvent.GetEventHandle(), waitTime ) != WAIT_OBJECT_0 ) { CIPAddr ipFrom; int len = g_pPortalMCSocket->RecvFrom( data.Base(), data.Count(), &ipFrom ); if ( len == -1 ) { waitTime = 20; } else { // These lengths must match exactly what is sent in ReceivePortalFlow. if ( len == 2 + sizeof( g_PortalMCThreadUniqueID ) + sizeof( int ) + portalbytes ) { // Perform more validation... if ( data[0] == VMPI_VVIS_PACKET_ID && data[1] == VMPI_PORTALFLOW_RESULTS ) { if ( *((unsigned long*)&data[2]) == g_PortalMCThreadUniqueID ) { int iWorkUnit = *((int*)&data[6]); if ( iWorkUnit >= 0 && iWorkUnit < g_numportals*2 ) { portal_t *p = sorted_portals[iWorkUnit]; if ( p ) { ++g_nMulticastPortalsReceived; memcpy( p->portalvis, &data[10], portalbytes ); p->status = stat_done; waitTime = 0; } } } } } } } return 0; }
int main(int argc, char* argv[]) { SpewOutputFunc( MySpewFunc ); // Figure out a random port to use. CCycleCount cnt; cnt.Sample(); CUniformRandomStream randomStream; randomStream.SetSeed( cnt.GetMicroseconds() ); int iPort = randomStream.RandomInt( 20000, 30000 ); g_ClientPacketEvent.Init( false, false ); // Setup the "server". CHandlerCreator_Server serverHandler; CIPAddr addr( 127, 0, 0, 1, iPort ); ITCPConnectSocket *pListener = ThreadedTCP_CreateListener( &serverHandler, (unsigned short)iPort ); // Setup the "client". CHandlerCreator_Client clientCreator; ITCPConnectSocket *pConnector = ThreadedTCP_CreateConnector( CIPAddr( 127, 0, 0, 1, iPort ), CIPAddr(), &clientCreator ); // Wait for them to connect. while ( !g_pClientSocket ) { if ( !pConnector->Update( &g_pClientSocket ) ) { Error( "Error in client connector!\n" ); } } pConnector->Release(); while ( !g_pServerSocket ) { if ( !pListener->Update( &g_pServerSocket ) ) Error( "Error in server connector!\n" ); } pListener->Release(); // Send some data. __int64 totalBytes = 0; CCycleCount startTime; int iPacket = 1; startTime.Sample(); CUtlVector<char> buf; while ( (GetAsyncKeyState( VK_SHIFT ) & 0x8000) == 0 ) { int size = randomStream.RandomInt( 1024*0, 1024*320 ); if ( buf.Count() < size ) buf.SetSize( size ); if ( g_pClientSocket->Send( buf.Base(), size ) ) { // Server receives the data and echoes it back. Verify that the data is good. WaitForSingleObject( g_ClientPacketEvent.GetEventHandle(), INFINITE ); Assert( memcmp( g_ClientPacket.Base(), buf.Base(), size ) == 0 ); totalBytes += size; CCycleCount curTime, elapsed; curTime.Sample(); CCycleCount::Sub( curTime, startTime, elapsed ); double flSeconds = elapsed.GetSeconds(); Msg( "Packet %d, %d bytes, %dk/sec\n", iPacket++, size, (int)(((totalBytes+511)/1024) / flSeconds) ); } } g_pClientSocket->Release(); g_pServerSocket->Release(); return 0; }