Team Fortress 2 Source Code as on 22/4/2020
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

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. // ThreadedTCPSocketTest.cpp : Defines the entry point for the console application.
  9. //
  10. #include "stdafx.h"
  11. #include "IThreadedTCPSocket.h"
  12. #include "threadhelpers.h"
  13. #include "vstdlib/random.h"
  14. CCriticalSection g_MsgCS;
  15. IThreadedTCPSocket *g_pClientSocket = NULL;
  16. IThreadedTCPSocket *g_pServerSocket = NULL;
  17. CEvent g_ClientPacketEvent;
  18. CUtlVector<char> g_ClientPacket;
  19. SpewRetval_t MySpewFunc( SpewType_t type, char const *pMsg )
  20. {
  21. CCriticalSectionLock csLock( &g_MsgCS );
  22. csLock.Lock();
  23. printf( "%s", pMsg );
  24. OutputDebugString( pMsg );
  25. csLock.Unlock();
  26. if( type == SPEW_ASSERT )
  27. return SPEW_DEBUGGER;
  28. else if( type == SPEW_ERROR )
  29. return SPEW_ABORT;
  30. else
  31. return SPEW_CONTINUE;
  32. }
  33. class CHandler_Server : public ITCPSocketHandler
  34. {
  35. public:
  36. virtual void Init( IThreadedTCPSocket *pSocket )
  37. {
  38. }
  39. virtual void OnPacketReceived( CTCPPacket *pPacket )
  40. {
  41. // Echo the data back.
  42. g_pServerSocket->Send( pPacket->GetData(), pPacket->GetLen() );
  43. pPacket->Release();
  44. }
  45. virtual void OnError( int errorCode, const char *pErrorString )
  46. {
  47. Msg( "Server error: %s\n", pErrorString );
  48. }
  49. };
  50. class CHandler_Client : public ITCPSocketHandler
  51. {
  52. public:
  53. virtual void Init( IThreadedTCPSocket *pSocket )
  54. {
  55. }
  56. virtual void OnPacketReceived( CTCPPacket *pPacket )
  57. {
  58. if ( g_ClientPacket.Count() < pPacket->GetLen() )
  59. g_ClientPacket.SetSize( pPacket->GetLen() );
  60. memcpy( g_ClientPacket.Base(), pPacket->GetData(), pPacket->GetLen() );
  61. g_ClientPacketEvent.SetEvent();
  62. pPacket->Release();
  63. }
  64. virtual void OnError( int errorCode, const char *pErrorString )
  65. {
  66. Msg( "Client error: %s\n", pErrorString );
  67. }
  68. };
  69. class CHandlerCreator_Server : public IHandlerCreator
  70. {
  71. public:
  72. virtual ITCPSocketHandler* CreateNewHandler()
  73. {
  74. return new CHandler_Server;
  75. }
  76. };
  77. class CHandlerCreator_Client : public IHandlerCreator
  78. {
  79. public:
  80. virtual ITCPSocketHandler* CreateNewHandler()
  81. {
  82. return new CHandler_Client;
  83. }
  84. };
  85. int main(int argc, char* argv[])
  86. {
  87. SpewOutputFunc( MySpewFunc );
  88. // Figure out a random port to use.
  89. CCycleCount cnt;
  90. cnt.Sample();
  91. CUniformRandomStream randomStream;
  92. randomStream.SetSeed( cnt.GetMicroseconds() );
  93. int iPort = randomStream.RandomInt( 20000, 30000 );
  94. g_ClientPacketEvent.Init( false, false );
  95. // Setup the "server".
  96. CHandlerCreator_Server serverHandler;
  97. CIPAddr addr( 127, 0, 0, 1, iPort );
  98. ITCPConnectSocket *pListener = ThreadedTCP_CreateListener(
  99. &serverHandler,
  100. (unsigned short)iPort );
  101. // Setup the "client".
  102. CHandlerCreator_Client clientCreator;
  103. ITCPConnectSocket *pConnector = ThreadedTCP_CreateConnector(
  104. CIPAddr( 127, 0, 0, 1, iPort ),
  105. CIPAddr(),
  106. &clientCreator );
  107. // Wait for them to connect.
  108. while ( !g_pClientSocket )
  109. {
  110. if ( !pConnector->Update( &g_pClientSocket ) )
  111. {
  112. Error( "Error in client connector!\n" );
  113. }
  114. }
  115. pConnector->Release();
  116. while ( !g_pServerSocket )
  117. {
  118. if ( !pListener->Update( &g_pServerSocket ) )
  119. Error( "Error in server connector!\n" );
  120. }
  121. pListener->Release();
  122. // Send some data.
  123. __int64 totalBytes = 0;
  124. CCycleCount startTime;
  125. int iPacket = 1;
  126. startTime.Sample();
  127. CUtlVector<char> buf;
  128. while ( (GetAsyncKeyState( VK_SHIFT ) & 0x8000) == 0 )
  129. {
  130. int size = randomStream.RandomInt( 1024*0, 1024*320 );
  131. if ( buf.Count() < size )
  132. buf.SetSize( size );
  133. if ( g_pClientSocket->Send( buf.Base(), size ) )
  134. {
  135. // Server receives the data and echoes it back. Verify that the data is good.
  136. WaitForSingleObject( g_ClientPacketEvent.GetEventHandle(), INFINITE );
  137. Assert( memcmp( g_ClientPacket.Base(), buf.Base(), size ) == 0 );
  138. totalBytes += size;
  139. CCycleCount curTime, elapsed;
  140. curTime.Sample();
  141. CCycleCount::Sub( curTime, startTime, elapsed );
  142. double flSeconds = elapsed.GetSeconds();
  143. Msg( "Packet %d, %d bytes, %dk/sec\n", iPacket++, size, (int)(((totalBytes+511)/1024) / flSeconds) );
  144. }
  145. }
  146. g_pClientSocket->Release();
  147. g_pServerSocket->Release();
  148. return 0;
  149. }