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

模拟服务器

开发平台:

C/C++

  1. #include "GameServerWorkerThread.h"
  2. //[ Include in ...IPCPServer
  3. #include "IOCPServerUtils.h"
  4. #include "IOCPServertstring.h"
  5. #include "IOCPServerException.h"
  6. //]
  7. //[ Include in ...Protocol
  8. #include "ProtocolProtocol.h"
  9. //]
  10. /*
  11.  * Using directives
  12.  */
  13. using OnlineGameLib::Win32::CIOCompletionPort;
  14. using OnlineGameLib::Win32::CIOBuffer;
  15. using OnlineGameLib::Win32::CSocketServer;
  16. using OnlineGameLib::Win32::Output;
  17. using OnlineGameLib::Win32::OutPutInfo;
  18. using OnlineGameLib::Win32::_tstring;
  19. using OnlineGameLib::Win32::CException;
  20. using OnlineGameLib::Win32::ToString;
  21. using OnlineGameLib::Win32::DumpData;
  22. CGameServerWorkerThread::CGameServerWorkerThread(
  23.  CIOCompletionPort &iocp)
  24.    : CSocketServer::WorkerThread(iocp)
  25. {
  26. }
  27. CGameServerWorkerThread::~CGameServerWorkerThread()
  28. {
  29. }
  30. void CGameServerWorkerThread::OnBeginProcessing()
  31. {
  32. Output( _T("OnBeginProcessing") );
  33. }
  34. void CGameServerWorkerThread::ReadCompleted(
  35. CSocketServer::Socket *pSocket,
  36. CIOBuffer *pBuffer)
  37. {
  38. try
  39. {
  40. pBuffer = ProcessDataStream( pSocket, pBuffer );
  41. pSocket->Read( pBuffer );
  42. }
  43. catch(const CException &e)
  44. {
  45. Output( _T("ReadCompleted - Exception - ") + e.GetWhere() + _T(" - ") + e.GetMessage() );
  46. pSocket->Shutdown();
  47. }
  48. catch(...)
  49. {
  50. Output( _T("ReadCompleted - Unexpected exception") );
  51. pSocket->Shutdown();
  52. }
  53. }
  54. void CGameServerWorkerThread::OnEndProcessing()
  55. {
  56. Output( _T("OnEndProcessing") );
  57. }
  58. void CGameServerWorkerThread::OnError( const OnlineGameLib::Win32::_tstring &message )
  59. {
  60. Output( _T("OnError - ") + message );
  61. }
  62. void CGameServerWorkerThread::ProcessCommand(
  63.    CSocketServer::Socket *pSocket,
  64.    const CIOBuffer *pBuffer) const
  65. {
  66. const BYTE *pPackData = pBuffer->GetBuffer();
  67. const size_t used = pBuffer->GetUsed();
  68. bool ok = false;
  69. WORD wDataLen = 0;
  70. PACK_HEADER ph = {0};
  71. if ( used > PACK_HEADER_LEN )
  72. {
  73. memcpy( &ph, pPackData, PACK_HEADER_LEN );
  74. wDataLen = ph.wDataLen;
  75. ok = true;
  76. }
  77. if ( ok )
  78. {
  79. const BYTE *pData = pPackData + PACK_HEADER_LEN;
  80. const size_t datalength = wDataLen;
  81. /*
  82.  * TODO : Process data receive from client
  83.  */
  84. // ==================== BEGIN =======================
  85. Output( _T("Package[length:") + ToString( wDataLen ) + _T("]n") + DumpData( pData, datalength, 40 ) );
  86. // ====================  END  =======================
  87. }
  88. else
  89. {
  90. Output( "found error and close this socket!" );
  91. pSocket->Close();
  92. }
  93. }
  94. size_t CGameServerWorkerThread::GetMinimumMessageSize() const
  95. {
  96. /*
  97.  * The smallest possible package we accept is pack-header
  98.  * once we have this many bytes we can start with try and work out
  99.  * what we have...
  100.  */
  101. return PACK_HEADER_LEN;
  102. }
  103. size_t CGameServerWorkerThread::GetMessageSize( const CIOBuffer *pBuffer ) const
  104. {
  105. const BYTE *pData = pBuffer->GetBuffer();
  106. const size_t used = pBuffer->GetUsed();
  107. PACK_HEADER ph = {0};
  108. /*
  109.  * First, verify the flag of a message
  110.  */
  111. if ( used > PACK_HEADER_LEN )
  112. {
  113. memcpy( &ph, pData, PACK_HEADER_LEN );
  114. if ( PACK_BEGIN_FLAG == ph.cPackBeginFlag && 
  115.  PACK_END_FLAG == ph.cPackEndFlag )
  116. {
  117. WORD wCRC = MAKE_CRC_DATE( PACK_BEGIN_FLAG, PACK_END_FLAG, ph.wDataLen );
  118. if ( ph.wCRCData == wCRC )
  119. {
  120. return ph.wDataLen + PACK_HEADER_LEN;
  121. }
  122. }
  123. }
  124. return 0;
  125. }
  126. CIOBuffer *CGameServerWorkerThread::ProcessDataStream(
  127. CSocketServer::Socket *pSocket,
  128. CIOBuffer *pBuffer) const
  129. {
  130. bool done;
  131. // DEBUG_ONLY( Output( _T("ProcessDataStream:n") + DumpData( pBuffer->GetBuffer(), pBuffer->GetUsed(), 40 ) ) );
  132. do
  133. {
  134. done = true;
  135. const size_t used = pBuffer->GetUsed();
  136. if ( used >= GetMinimumMessageSize() )
  137. {
  138. const size_t messageSize = GetMessageSize( pBuffer );
  139. if ( messageSize == 0 )
  140. {
  141. /*
  142.  * havent got a complete message yet.
  143.  * we null terminate our messages in the buffer, so we need to reserve
  144.  * a byte of the buffer for this purpose...
  145.  */
  146. if ( used == ( pBuffer->GetSize() - 1 ) )
  147. {
  148. Output( _T("Too much data!") );
  149. /*
  150.  * Write this message and then shutdown the sending side of the socket.
  151.  */
  152. Output( "found error and close this socket!" );
  153. pSocket->Close();
  154. /*
  155.  * throw the rubbish away
  156.  */
  157. pBuffer->Empty();
  158. done = true;
  159. }
  160. }
  161. else if ( used == messageSize )
  162. {
  163. Output( _T("Got complete, distinct, message") );
  164. /*
  165.  * we have a whole, distinct, message
  166.  */
  167. pBuffer->AddData(0);   // null terminate the command string;
  168. ProcessCommand( pSocket, pBuffer );
  169. pBuffer->Empty();
  170. done = true;
  171. }
  172. else if ( used > messageSize )
  173. {
  174. Output( _T("Got message plus extra data") );
  175. /*
  176.  * we have a message, plus some more data
  177.  * 
  178.  * allocate a new buffer, copy the extra data into it and try again...
  179.  */
  180. CIOBuffer *pMessage = pBuffer->SplitBuffer( messageSize );
  181. pMessage->AddData(0);   // null terminate the command string;
  182. ProcessCommand( pSocket, pMessage );
  183. pMessage->Release();
  184. /*
  185.  * loop again, we may have another complete message in there...
  186.  */
  187. done = false;
  188. }
  189. }
  190. }
  191. while ( !done );
  192. /*
  193.  * not enough data in the buffer, reissue a read into the same buffer to collect more data
  194.  */
  195. return pBuffer;
  196. }