/TGame/TTools/MysqlStressTest/MysqlStressTestManager/MysqlStressTestManager/Source/ConnecterManager.cpp

http://awoe.googlecode.com/ · C++ · 290 lines · 236 code · 40 blank · 14 comment · 39 complexity · b6b4d5e3c793366a3aaac0952e9ae461 MD5 · raw file

  1. //////////////////////////////////////////////////////////////////////////
  2. // ConnecterManager.cpp //
  3. // //
  4. // WYJ //
  5. // 2010.4 //
  6. // //
  7. //////////////////////////////////////////////////////////////////////////
  8. #include "stdafx.h"
  9. #include "ConnecterManager.h"
  10. #include <assert.h>
  11. #include "Connecter.h"
  12. #include "MessageHandler.h"
  13. #define PORT 5333
  14. #define MAX_CONNECTER 2000
  15. #define MSGSIZE 1024
  16. #define WM_CONNECTERNOTIFY WM_USER + 101
  17. DWORD WINAPI ReceiveThread( LPVOID lpParam )
  18. {
  19. ConnecterManager* pConnecterManager = (ConnecterManager *)lpParam;
  20. int i;
  21. fd_set fdread;
  22. int ret;
  23. struct timeval tv = {1, 0};
  24. char szMessage[MSGSIZE];
  25. while (TRUE)
  26. {
  27. FD_ZERO(&fdread);
  28. for (i = 0; i < pConnecterManager->GetConnecterNum(); i++)
  29. {
  30. FD_SET( pConnecterManager->GetConnecter( i )->sock, &fdread );
  31. }
  32. // We only care read event
  33. ret = select( 0, &fdread, NULL, NULL, &tv );
  34. if (ret == 0)
  35. {
  36. // Time expired
  37. continue;
  38. }
  39. for ( i = 0; i < pConnecterManager->GetConnecterNum(); i++ )
  40. {
  41. if ( FD_ISSET( pConnecterManager->GetConnecter( i )->sock, &fdread ) )
  42. {
  43. // A read event happened on g_CliSocketArr[i]
  44. ret = recv( pConnecterManager->GetConnecter( i )->sock, szMessage, MSGSIZE, 0 );
  45. if ( ret == 0 || ( ret == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET ) )
  46. {
  47. // Client socket closed
  48. pConnecterManager->RemoveConnecter( i );
  49. }
  50. else
  51. {
  52. // We received a message from client
  53. pConnecterManager->DispatchMessage( i, szMessage );
  54. }
  55. }
  56. }
  57. }
  58. return 0;
  59. }
  60. DWORD WINAPI ListenThread( LPVOID lpParam )
  61. {
  62. ConnecterManager* pConnecterManager = (ConnecterManager *)lpParam;
  63. WSADATA wsaData;
  64. SOCKET sListen;
  65. SOCKET sConnecter;
  66. SOCKADDR_IN connecter;
  67. int iaddrSize = sizeof(SOCKADDR_IN);
  68. DWORD dwReceiveThreadId;
  69. if ( WSAStartup( 0x0202, &wsaData ) )
  70. {
  71. }
  72. sListen = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
  73. pConnecterManager->SetListenSocket( sListen );
  74. bind(sListen, (struct sockaddr *)pConnecterManager->GetListenAddr(), sizeof(SOCKADDR_IN));
  75. listen( sListen, 3 );
  76. CreateThread(NULL, 0, ReceiveThread, pConnecterManager, 0, &dwReceiveThreadId);
  77. pConnecterManager->SetReceiveThreadID( dwReceiveThreadId );
  78. while (TRUE)
  79. {
  80. // Accept a connection
  81. sConnecter = accept( sListen, (struct sockaddr *)&connecter, &iaddrSize );
  82. pConnecterManager->AddConnecter( sConnecter, &connecter );
  83. }
  84. return 0;
  85. }
  86. ///////////////////////////////////////////////////////////////////////////////////
  87. ConnecterManager::ConnecterManager( void )
  88. : m_ConnecterNum( 0 ), m_Connecter( NULL ), m_AddrMapNum( 0 ), m_ListenSocket( NULL ),
  89. m_ListenThreadID( 0 ), m_ReceiveThreadID( 0 ), m_pMessageHandler( NULL ), m_hWnd( NULL )
  90. {
  91. m_ListenAddr.sin_addr.S_un.S_addr = htonl( INADDR_ANY );
  92. m_ListenAddr.sin_family = AF_INET;
  93. m_ListenAddr.sin_port = htons( PORT );
  94. }
  95. ConnecterManager::~ConnecterManager( void )
  96. {
  97. m_Mutex.Lock();
  98. for ( AddrMapIter iter = m_AddrMap.begin(); iter != m_AddrMap.end(); iter++ )
  99. {
  100. for ( ThreadMapIter i = iter->second.begin(); i != iter->second.end(); i++ )
  101. {
  102. if ( i->second->status != e_Close )
  103. {
  104. closesocket( i->second->sock );
  105. }
  106. delete i->second;
  107. }
  108. }
  109. delete [] m_Connecter;
  110. m_Mutex.Unlock();
  111. if ( m_pMessageHandler )
  112. {
  113. delete m_pMessageHandler;
  114. }
  115. }
  116. bool ConnecterManager::Initialize( void )
  117. {
  118. assert( m_pMessageHandler == NULL );
  119. m_pMessageHandler = new MessageHandler( this );
  120. assert( m_Connecter == NULL );
  121. m_Connecter = new Connecter*[MAX_CONNECTER];
  122. if ( !m_Connecter )
  123. {
  124. char buf[1024];
  125. sprintf_s( buf, 1024, "Initialize connecter manager failed." );
  126. MessageBox( NULL, buf, 0, 0 );
  127. return false;
  128. }
  129. CreateThread( NULL, 0, ListenThread, this, 0, &m_ListenThreadID );
  130. return true;
  131. }
  132. void ConnecterManager::SetListenSocket( SOCKET sock )
  133. {
  134. m_ListenSocket = sock;
  135. }
  136. const SOCKADDR_IN* ConnecterManager::GetListenAddr( void )
  137. {
  138. return &m_ListenAddr;
  139. }
  140. void ConnecterManager::AddConnecter( SOCKET sock, const SOCKADDR_IN* addr )
  141. {
  142. if ( m_ConnecterNum >= MAX_CONNECTER )
  143. {
  144. char buf[1024];
  145. sprintf_s( buf, 1024, "Add a new connecter failed for over the max connecter number %d", MAX_CONNECTER );
  146. MessageBox( NULL, buf, 0, 0 );
  147. }
  148. m_Mutex.Lock();
  149. m_Connecter[m_ConnecterNum] = new Connecter;
  150. m_Connecter[m_ConnecterNum]->sock = sock;
  151. memcpy( m_Connecter[m_ConnecterNum]->ip, inet_ntoa( addr->sin_addr ), 16 );
  152. m_Connecter[m_ConnecterNum]->thread_id = 0;
  153. m_Connecter[m_ConnecterNum]->status = e_None;
  154. m_ConnecterNum++;
  155. m_Mutex.Unlock();
  156. }
  157. void ConnecterManager::SetReceiveThreadID( DWORD threadID )
  158. {
  159. m_ReceiveThreadID = threadID;
  160. }
  161. int ConnecterManager::GetConnecterNum( void )
  162. {
  163. return m_ConnecterNum;
  164. }
  165. Connecter* ConnecterManager::GetConnecter( int index )
  166. {
  167. return index >= m_ConnecterNum ? NULL : m_Connecter[index];
  168. }
  169. bool ConnecterManager::RemoveConnecter( int index )
  170. {
  171. if ( index >= m_ConnecterNum )
  172. {
  173. char buf[1024];
  174. sprintf_s( buf, 1024, "Remove a not exist connect index %d", index );
  175. MessageBox( NULL, buf, 0, 0 );
  176. }
  177. m_Mutex.Lock();
  178. if ( m_Connecter[index]->status == e_Close )
  179. {
  180. char buf[1024];
  181. sprintf_s( buf, 1024, "Remove a closed connect index %d", index );
  182. MessageBox( NULL, buf, 0, 0 );
  183. m_Mutex.Unlock();
  184. return false;
  185. }
  186. closesocket( m_Connecter[index]->sock );
  187. m_Connecter[index]->status = e_Close;
  188. Notify( m_Connecter[index] );
  189. m_Connecter[index] = m_Connecter[--m_ConnecterNum];
  190. m_Connecter[m_ConnecterNum] = NULL;
  191. m_Mutex.Unlock();
  192. return true;
  193. }
  194. void ConnecterManager::DispatchMessage( int index, const char * msg )
  195. {
  196. m_pMessageHandler->HandleMessage( index, msg );
  197. }
  198. bool ConnecterManager::InitConnecter( int index, DWORD threadID )
  199. {
  200. if ( index >= m_ConnecterNum )
  201. {
  202. char buf[1024];
  203. sprintf_s( buf, 1024, "Initialize a not exist connect index %d", index );
  204. MessageBox( NULL, buf, 0, 0 );
  205. }
  206. m_Mutex.Lock();
  207. m_Connecter[index]->thread_id = threadID;
  208. m_Connecter[index]->status = e_Ready;
  209. AddrMapIter iter = m_AddrMap.find( inet_addr( m_Connecter[index]->ip ) );
  210. if ( iter == m_AddrMap.end() )
  211. {
  212. m_AddrMap.insert( AddrMap::value_type( inet_addr( m_Connecter[index]->ip ), ThreadMap() ) );
  213. iter = m_AddrMap.find( inet_addr( m_Connecter[index]->ip ) );
  214. }
  215. if ( iter != m_AddrMap.end() )
  216. {
  217. ThreadMapIter i = iter->second.find( threadID );
  218. if ( i != iter->second.end() )
  219. {
  220. delete i->second;
  221. i->second = m_Connecter[index];
  222. }
  223. else
  224. {
  225. iter->second.insert( ThreadMap::value_type( threadID, m_Connecter[index] ) );
  226. }
  227. Notify( m_Connecter[index] );
  228. }
  229. m_Mutex.Unlock();
  230. return true;
  231. }
  232. void ConnecterManager::SetHwnd( HWND hWnd )
  233. {
  234. m_hWnd = hWnd;
  235. }
  236. Connecter* ConnecterManager::GetConnecter( unsigned long addr, DWORD threadID )
  237. {
  238. AddrMapIter iter = m_AddrMap.find( addr );
  239. if ( iter != m_AddrMap.end() )
  240. {
  241. ThreadMapIter i = iter->second.find( threadID );
  242. if ( i != iter->second.end() )
  243. return i->second;
  244. }
  245. return NULL;
  246. }
  247. void ConnecterManager::Notify( Connecter* pConnecter )
  248. {
  249. SendMessage( m_hWnd, WM_CONNECTERNOTIFY, (WPARAM)0, (LPARAM)pConnecter );
  250. }