testIOCPServer.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:6k
源码类别:

模拟服务器

开发平台:

C/C++

  1. // testIOCPServer.cpp : Defines the entry point for the console application.
  2. //
  3. #include <winsock2.h>
  4. //[ Include in ...IPCPServer
  5. #include "IOCPServerException.h"
  6. #include "IOCPServerUtils.h"
  7. #include "IOCPServerManualResetEvent.h"
  8. #include "IOCPServerSocketServer.h"
  9. #include "IOCPServertstring.h"
  10. //]
  11. #include "GameServer.h"
  12. using OnlineGameLib::Win32::_tstring;
  13. using OnlineGameLib::Win32::CException;
  14. using OnlineGameLib::Win32::Output;
  15. using OnlineGameLib::Win32::OutPutInfo;
  16. using OnlineGameLib::Win32::CManualResetEvent;
  17. using OnlineGameLib::Win32::CCriticalSection;
  18. using OnlineGameLib::Win32::ToString;
  19. using OnlineGameLib::Win32::GetTimeStamp;
  20. #include "stack"
  21. #include "map"
  22. using namespace std;
  23. #if _MSC_VER > 1020 // if VC++ version is > 4.2
  24. using namespace std; // std c++ libs implemented in std
  25. #endif
  26. /*
  27.  * Manager of client
  28.  */
  29. #define MAX_NUMOF_CLIENT 1000
  30. typedef map< DWORD, DWORD > INDEX2CLIENT;
  31. INDEX2CLIENT g_lClientSocket;
  32. typedef stack< DWORD > STACK;
  33. STACK g_vFreeClient;
  34. CCriticalSection g_csClient;
  35. void Init();
  36. void DeInit();
  37. bool AddClient( OnlineGameLib::Win32::CSocketServer::Socket *pSocket );
  38. bool DelClient( OnlineGameLib::Win32::CSocketServer::Socket *pSocket );
  39. void SendDataToAllClient( const char *pData, size_t dataLength );
  40. /*
  41.  * Performance
  42.  */
  43. LARGE_INTEGER g_theFrequency = {0};
  44. /*
  45.  * Entrance of the application
  46.  */
  47. int main(int argc, char* argv[])
  48. {
  49. ::QueryPerformanceFrequency( &g_theFrequency );
  50. Init();
  51. try
  52. {
  53. CGameServer server(
  54. "Welcome to jx.online server! What are you doing now?",
  55. INADDR_ANY,                   // address to listen on
  56. 5001,                         // port to listen on
  57. 10,                           // max number of sockets to keep in the pool
  58. 10,                           // max number of buffers to keep in the pool
  59. 1024);                        // buffer size 
  60. server.Start();
  61. server.StartAcceptingConnections();
  62. char szBuffer[1000] = {0};
  63. memset( szBuffer, '.', 1000 );
  64. memcpy( szBuffer, "BEGIN", strlen("BEGIN") );
  65. memcpy( szBuffer+1000-strlen("END"), "END", 3 );
  66. LARGE_INTEGER thePerformanceCount_Begin = {0};
  67. LARGE_INTEGER thePerformanceCount_End = {0};
  68. while ( true )
  69. {
  70. ::QueryPerformanceCounter( &thePerformanceCount_Begin );
  71. /*
  72.  * Send some data to all client
  73.  */
  74. SendDataToAllClient( szBuffer, 1000 );
  75. ::QueryPerformanceCounter( &thePerformanceCount_End );
  76. /*
  77.  * 20 frame percent one second
  78.  */
  79. LONGLONG l64nInterval = thePerformanceCount_End.QuadPart - thePerformanceCount_Begin.QuadPart;
  80. LONGLONG l64nLeave = g_theFrequency.QuadPart / 50 - l64nInterval;
  81. while ( l64nLeave >= 0 )
  82. {
  83. ::QueryPerformanceCounter( &thePerformanceCount_Begin );
  84. l64nInterval = thePerformanceCount_Begin.QuadPart - thePerformanceCount_End.QuadPart;
  85. l64nLeave -= l64nInterval;
  86. thePerformanceCount_End.QuadPart = thePerformanceCount_Begin.QuadPart;
  87. ::Sleep( 1 );
  88. }
  89. }
  90. CManualResetEvent shutdownEvent(_T("OnlineGameServerShutdown"), false);
  91. CManualResetEvent pauseResumeEvent(_T("OnlineGameServerPauseResume"), false);
  92. HANDLE handlesToWaitFor[2];
  93. handlesToWaitFor[0] = shutdownEvent.GetEvent();
  94. handlesToWaitFor[1] = pauseResumeEvent.GetEvent();
  95. bool accepting = true;
  96. bool done = false;
  97. while (!done)
  98. {
  99. DWORD waitResult = ::WaitForMultipleObjects(2, handlesToWaitFor, false, INFINITE);
  100. if (waitResult == WAIT_OBJECT_0)
  101. {
  102. done = true;
  103. }
  104. else if (waitResult == WAIT_OBJECT_0 + 1)
  105. {
  106. if (accepting)
  107. {
  108. server.StopAcceptingConnections();
  109. }
  110. else
  111. {
  112. server.StartAcceptingConnections();
  113. }
  114. accepting = !accepting;
  115. }
  116. else
  117. {
  118. Output(_T("Unexpected result from WaitForMultipleObjects - exiting"));
  119. done = true;
  120. }
  121. }
  122. server.WaitForShutdownToComplete();
  123. }
  124. catch(const CException &e)
  125. {
  126. Output(_T("Exception: ") + e.GetWhere() + _T(" - ") + e.GetMessage());
  127. }
  128. catch(...)
  129. {
  130. Output(_T("Unexpected exception"));
  131. }
  132. DeInit();
  133. return 0;
  134. }
  135. bool AddClient( OnlineGameLib::Win32::CSocketServer::Socket *pSocket )
  136. {
  137. CCriticalSection::Owner lock( g_csClient );
  138. if ( !g_vFreeClient.empty() )
  139. {
  140. DWORD dwIndex = g_vFreeClient.top();
  141. g_vFreeClient.pop();
  142. pSocket->SetUserData( dwIndex );
  143. g_lClientSocket.insert( INDEX2CLIENT::value_type( dwIndex, reinterpret_cast<DWORD>(pSocket) ) );
  144. OutPutInfo( GetTimeStamp() + _T("=> Add a client [current total:") + 
  145. ToString( g_lClientSocket.size() ) +
  146. _T( "]" ) );
  147. return true;
  148. }
  149. return false;
  150. }
  151. bool DelClient( OnlineGameLib::Win32::CSocketServer::Socket *pSocket )
  152. {
  153. CCriticalSection::Owner lock( g_csClient );
  154. if ( !g_lClientSocket.empty() )
  155. {
  156. DWORD index = pSocket->GetUserData();
  157. g_lClientSocket.erase( index );
  158. g_vFreeClient.push( index );
  159. OutPutInfo( GetTimeStamp() + _T("=> Del a client [current total:") + 
  160. ToString( g_lClientSocket.size() ) + 
  161. _T( "]" ) );
  162. return true;
  163. }
  164. return false;
  165. }
  166. void SendDataToAllClient( const char *pData, size_t dataLength )
  167. {
  168. CCriticalSection::Owner lock( g_csClient );
  169. for( INDEX2CLIENT::iterator index = g_lClientSocket.begin();
  170. index != g_lClientSocket.end();
  171. index ++ )
  172. {
  173. OnlineGameLib::Win32::CSocketServer::Socket *pSocket = 
  174. reinterpret_cast<OnlineGameLib::Win32::CSocketServer::Socket *>((*index).second);
  175. if ( pSocket )
  176. {
  177. pSocket->Write( pData, dataLength );
  178. }
  179. }
  180. }
  181. void Init()
  182. {
  183. for ( DWORD i = 0; i<MAX_NUMOF_CLIENT; i++ )
  184. {
  185. g_vFreeClient.push( i );
  186. }
  187. }
  188. void DeInit()
  189. {
  190. while ( !g_vFreeClient.empty() )
  191. {
  192. g_vFreeClient.pop();
  193. }
  194. g_lClientSocket.erase( g_lClientSocket.begin(), g_lClientSocket.end() );
  195. }