You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
4.1 KiB
198 lines
4.1 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
// |
|
//=============================================================================// |
|
// ThreadedTCPSocketTest.cpp : Defines the entry point for the console application. |
|
// |
|
|
|
#include "stdafx.h" |
|
#include "IThreadedTCPSocket.h" |
|
#include "threadhelpers.h" |
|
#include "vstdlib/random.h" |
|
|
|
|
|
CCriticalSection g_MsgCS; |
|
|
|
|
|
IThreadedTCPSocket *g_pClientSocket = NULL; |
|
IThreadedTCPSocket *g_pServerSocket = NULL; |
|
|
|
CEvent g_ClientPacketEvent; |
|
CUtlVector<char> g_ClientPacket; |
|
|
|
|
|
|
|
SpewRetval_t MySpewFunc( SpewType_t type, char const *pMsg ) |
|
{ |
|
CCriticalSectionLock csLock( &g_MsgCS ); |
|
csLock.Lock(); |
|
|
|
printf( "%s", pMsg ); |
|
OutputDebugString( pMsg ); |
|
|
|
csLock.Unlock(); |
|
|
|
if( type == SPEW_ASSERT ) |
|
return SPEW_DEBUGGER; |
|
else if( type == SPEW_ERROR ) |
|
return SPEW_ABORT; |
|
else |
|
return SPEW_CONTINUE; |
|
} |
|
|
|
|
|
class CHandler_Server : public ITCPSocketHandler |
|
{ |
|
public: |
|
virtual void Init( IThreadedTCPSocket *pSocket ) |
|
{ |
|
} |
|
|
|
virtual void OnPacketReceived( CTCPPacket *pPacket ) |
|
{ |
|
// Echo the data back. |
|
g_pServerSocket->Send( pPacket->GetData(), pPacket->GetLen() ); |
|
pPacket->Release(); |
|
} |
|
|
|
virtual void OnError( int errorCode, const char *pErrorString ) |
|
{ |
|
Msg( "Server error: %s\n", pErrorString ); |
|
} |
|
}; |
|
|
|
|
|
|
|
class CHandler_Client : public ITCPSocketHandler |
|
{ |
|
public: |
|
virtual void Init( IThreadedTCPSocket *pSocket ) |
|
{ |
|
} |
|
|
|
virtual void OnPacketReceived( CTCPPacket *pPacket ) |
|
{ |
|
if ( g_ClientPacket.Count() < pPacket->GetLen() ) |
|
g_ClientPacket.SetSize( pPacket->GetLen() ); |
|
|
|
memcpy( g_ClientPacket.Base(), pPacket->GetData(), pPacket->GetLen() ); |
|
g_ClientPacketEvent.SetEvent(); |
|
pPacket->Release(); |
|
} |
|
|
|
virtual void OnError( int errorCode, const char *pErrorString ) |
|
{ |
|
Msg( "Client error: %s\n", pErrorString ); |
|
} |
|
}; |
|
|
|
|
|
|
|
class CHandlerCreator_Server : public IHandlerCreator |
|
{ |
|
public: |
|
virtual ITCPSocketHandler* CreateNewHandler() |
|
{ |
|
return new CHandler_Server; |
|
} |
|
}; |
|
|
|
class CHandlerCreator_Client : public IHandlerCreator |
|
{ |
|
public: |
|
virtual ITCPSocketHandler* CreateNewHandler() |
|
{ |
|
return new CHandler_Client; |
|
} |
|
}; |
|
|
|
|
|
|
|
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; |
|
} |
|
|
|
|