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

模拟服务器

开发平台:

C/C++

  1. #include "JXClient.h"
  2. //[ Include in ...IPCPServer
  3. #include "IOCPServerException.h"
  4. #include "IOCPServerUtils.h"
  5. #include "IOCPServerManualResetEvent.h"
  6. //]
  7. //[ Include in ...Protocol
  8. #include "ProtocolProtocol.h"
  9. //]
  10. #include "GameClient.h"
  11. using OnlineGameLib::Win32::_tstring;
  12. using OnlineGameLib::Win32::CException;
  13. using OnlineGameLib::Win32::Output;
  14. using OnlineGameLib::Win32::CManualResetEvent;
  15. using OnlineGameLib::Win32::GetTimeStamp;
  16. using OnlineGameLib::Win32::OutPutInfo;
  17. using OnlineGameLib::Win32::ToString;
  18. using OnlineGameLib::Win32::CCriticalSection;
  19. using OnlineGameLib::Win32::DumpData;
  20. static CGameClient g_theJXClient( MAX_BUFFER_KEEPINPOOL, EXTEND_BUFFER_SIZE );
  21. static CConnectManager g_theManager( MAX_BUFFER_KEEPINPOOL, EXTEND_BUFFER_SIZE );
  22. CConnectManager::CConnectManager(
  23. size_t maxFreeBuffers, 
  24. size_t bufferSize /*1024*/ )
  25. : OnlineGameLib::Win32::CIOBuffer::Allocator(bufferSize, maxFreeBuffers),
  26. m_pfnCallbackClientEvent(NULL)
  27. {
  28. m_pReadBuffer = Allocate();
  29. m_pRecvBuffer = Allocate();
  30. }
  31. CConnectManager::~CConnectManager()
  32. {
  33. try
  34. {
  35. Flush();
  36. }
  37. catch(...)
  38. {
  39. }
  40. }
  41. void CConnectManager::ConnectServer()
  42. {
  43. if ( m_pfnCallbackClientEvent )
  44. {
  45. m_pfnCallbackClientEvent( SERVER_CONNECT_CREATE );
  46. }
  47. }
  48. void CConnectManager::DisConnetServer()
  49. {
  50. if ( m_pfnCallbackClientEvent )
  51. {
  52. m_pfnCallbackClientEvent( SERVER_CONNECT_CLOSE );
  53. }
  54. }
  55. void CConnectManager::RecvFromServer( const char *pData, size_t dataLength )
  56. {
  57. m_pRecvBuffer->AddData( pData, dataLength );
  58. }
  59. const char *CConnectManager::GetFromClient( size_t &dataLength )
  60. {
  61. m_pReadBuffer->Empty();
  62. m_pRecvBuffer = ProcessDataStream( m_pRecvBuffer );
  63. const BYTE *pPackData = m_pReadBuffer->GetBuffer();
  64. dataLength = m_pReadBuffer->GetUsed();
  65. //[
  66. #ifdef NETWORK_DEBUG
  67. // sizeof(DWORD) == 4
  68. // assert( dataLength > 4 && "Get error buffer from server!" );
  69. if (dataLength)
  70. {
  71. //assert( dataLength > 4 && "Get error buffer from server!" );
  72. dataLength -= 4;
  73. }
  74. #endif //NETWORK_DEBUG
  75. //]
  76. return reinterpret_cast<const char*>( pPackData );
  77. }
  78. void CConnectManager::ProcessCommand( const OnlineGameLib::Win32::CIOBuffer *pBuffer)
  79. {
  80. const BYTE *pPackData = pBuffer->GetBuffer();
  81. const size_t used = pBuffer->GetUsed();
  82. bool ok = false;
  83. WORD wDataLen = 0;
  84. PACK_HEADER ph = {0};
  85. if ( used > PACK_HEADER_LEN )
  86. {
  87. memcpy( &ph, pPackData, PACK_HEADER_LEN );
  88. wDataLen = ph.wDataLen;
  89. ok = true;
  90. }
  91. if ( ok )
  92. {
  93. const BYTE *pData = pPackData + PACK_HEADER_LEN;
  94. const size_t datalength = wDataLen;
  95. /*
  96.  * TODO : Process data receive from server
  97.  */
  98. Output( _T("Get a package[length:") + ToString( wDataLen ) + _T("]n") + DumpData( pData, datalength, 40 ) );
  99. m_pReadBuffer->AddData( pData, datalength );
  100. }
  101. else
  102. {
  103. Output( "found error and close this connection!" );
  104. Shutdown();
  105. }
  106. }
  107. size_t CConnectManager::GetMinimumMessageSize() const
  108. {
  109. /*
  110.  * The smallest possible package we accept is pack-header
  111.  * once we have this many bytes we can start with try and work out
  112.  * what we have...
  113.  */
  114. return PACK_HEADER_LEN;
  115. }
  116. size_t CConnectManager::GetMessageSize( 
  117. const OnlineGameLib::Win32::CIOBuffer *pBuffer ) const
  118. {
  119. const BYTE *pData = pBuffer->GetBuffer();
  120. const size_t used = pBuffer->GetUsed();
  121. PACK_HEADER ph = {0};
  122. /*
  123.  * First, verify the flag of a message
  124.  */
  125. if ( used > PACK_HEADER_LEN )
  126. {
  127. memcpy( &ph, pData, PACK_HEADER_LEN );
  128. if ( PACK_BEGIN_FLAG == ph.cPackBeginFlag && 
  129.  PACK_END_FLAG == ph.cPackEndFlag )
  130. {
  131. WORD wCRC = MAKE_CRC_DATE( PACK_BEGIN_FLAG, PACK_END_FLAG, ph.wDataLen );
  132. if ( ph.wCRCData == wCRC )
  133. {
  134. return ph.wDataLen + PACK_HEADER_LEN;
  135. }
  136. }
  137. }
  138. return 0;
  139. }
  140. OnlineGameLib::Win32::CIOBuffer *CConnectManager::ProcessDataStream( 
  141. OnlineGameLib::Win32::CIOBuffer *pBuffer)
  142. {
  143. const size_t used = pBuffer->GetUsed();
  144. if ( used >= GetMinimumMessageSize() )
  145. {
  146. const size_t messageSize = GetMessageSize( pBuffer );
  147. if ( messageSize == 0 )
  148. {
  149. /*
  150.  * havent got a complete message yet.
  151.  * we null terminate our messages in the buffer, so we need to reserve
  152.  * a byte of the buffer for this purpose...
  153.  */
  154. if ( used == ( pBuffer->GetSize() - 1 ) )
  155. {
  156. Output( _T("Too much data!") );
  157. /*
  158.  * Write this message and then shutdown the sending side of the socket.
  159.  */
  160. Output( "found error and close this connection!" );
  161. Shutdown();
  162. /*
  163.  * throw the rubbish away
  164.  */
  165. pBuffer->Empty();
  166. }
  167. }
  168. else if ( used == messageSize )
  169. {
  170. Output( _T("Got complete, distinct, message") );
  171. /*
  172.  * we have a whole, distinct, message
  173.  */
  174. ProcessCommand( pBuffer );
  175. pBuffer->Empty();
  176. }
  177. else if (used > messageSize)
  178. {
  179. Output(_T("Got message plus extra data"));
  180. /*
  181.  * we have a message, plus some more data
  182.  * 
  183.  * allocate a new buffer, copy the extra data into it and try again...
  184.  */
  185. OnlineGameLib::Win32::CIOBuffer *pMessage = pBuffer->SplitBuffer( messageSize );
  186. ProcessCommand( pMessage );
  187. pMessage->Release();
  188. }
  189. }
  190. /*
  191.  * Reissue a read into the same buffer to collect more data
  192.  */
  193. return pBuffer;
  194. }
  195. bool ClientStartup( 
  196. JX_CLIENT_
  197. )
  198. {
  199. g_theJXClient.Start();
  200. return true;
  201. }
  202. void ClientCleanup( JX_CLIENT_ )
  203. {
  204. try
  205. {
  206. g_theJXClient.StopConnections();
  207. g_theJXClient.WaitForShutdownToComplete();
  208. }
  209. catch( const CException &e )
  210. {
  211. Output(_T("Exception: ") + e.GetWhere() + _T(" - ") + e.GetMessage());
  212. }
  213. catch(...)
  214. {
  215. Output(_T("Unexpected exception"));
  216. }
  217. }
  218. bool ConnectTo( 
  219. JX_CLIENT_
  220. const OnlineGameLib::Win32::_tstring &addressToConnectServer,
  221. unsigned short portToConnectServer )
  222. {
  223. bool ok = false;
  224. try
  225. {
  226. g_theJXClient.ConnectTo( addressToConnectServer, portToConnectServer );
  227. g_theJXClient.StartConnections();
  228. ok = true;
  229. }
  230. catch( const CException &e )
  231. {
  232. Output(_T("Exception: ") + e.GetWhere() + _T(" - ") + e.GetMessage());
  233. }
  234. catch(...)
  235. {
  236. Output(_T("Unexpected exception"));
  237. }
  238. return ok;
  239. }
  240. void InstallCallBack( JX_CLIENT_ CALLBACK_CLIENT_EVENT pfn )
  241. {
  242. g_theManager.InstallCallBack( pfn );
  243. }
  244. void Client_Start()
  245. {
  246. g_theJXClient.StartConnections();
  247. }
  248. void Client_Pause()
  249. {
  250. g_theJXClient.StopConnections();
  251. }
  252. void Client_Begin()
  253. {
  254. }
  255. void Client_End()
  256. {
  257. }
  258. /*
  259.  * Client usage
  260.  */
  261. void RecvFromServer( 
  262. JX_CLIENT_ 
  263. const char *pData, 
  264. size_t dataLength )
  265. {
  266. g_theManager.RecvFromServer( pData, dataLength );
  267. }
  268. const char *GetFromServer( size_t &dataLength )
  269. {
  270. return g_theManager.GetFromClient( dataLength );
  271. }
  272.  
  273. void SendToServer( 
  274. JX_CLIENT_ 
  275. void *pData, 
  276. size_t dataLength )
  277. {
  278. g_theJXClient.Write( reinterpret_cast<const char*>( pData ), dataLength );
  279. }
  280. void Shutdown( JX_CLIENT_ )
  281. {
  282. //g_theJXClient.InitiateShutdown();
  283. g_theJXClient.StopConnections();
  284. }
  285. void ConnectServer( JX_CLIENT_ )
  286. {
  287. g_theManager.ConnectServer();
  288. }
  289. void DisConnetServer( JX_CLIENT_ )
  290. {
  291. g_theManager.DisConnetServer();
  292. }