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

模拟服务器

开发平台:

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