/Server/Source/ClientDll/MuxCliMod/MuxCliMod/PkgProc/PacketBuild.h

https://bitbucket.org/Ryfon/mux · C Header · 164 lines · 98 code · 22 blank · 44 comment · 12 complexity · 43935270264ea0d6c580b121928335f0 MD5 · raw file

  1. /**
  2. * @file PacketBuild.h
  3. * @brief 组包模块头文件
  4. * Copyright(c) 2007,上海第九城市游戏研发部
  5. * All rights reserved
  6. * 文件名称: PacketBuild.h
  7. * 摘 要: 根据通信协议(类型,命令字,协议结构)进行组包
  8. * 作 者: dzj
  9. * 完成日期: 2007.12.04
  10. *
  11. */
  12. #pragma once
  13. #include "CliProtocol.h"
  14. static const unsigned char SELF_PROTO_TYPE = 0x00;//自身为客户端,定义见srvProtocol.h;
  15. static const int PKGBUILD_BUF_SIZE = MUX_PROTO::MAX_MSG_SIZE;//不要随意改动此值,因为底层网络模块的缓冲也有限制,只改动这一个值可能导致底层错误;
  16. /**
  17. 组包类,将待发信息加上包头
  18. 注意:应在单线程中使用,并且每次新组包会覆盖旧包,因此每次的组包都应即时发送出去;
  19. */
  20. class CPacketBuild
  21. {
  22. public:
  23. //组包函数;
  24. template < typename T_Msg >
  25. static bool CreatePkg( T_Msg* pPkg, char** pOutPkg, int& nOutLen )
  26. {
  27. //if ( pPkg->wCmd != T_Msg::wCmd )
  28. //{
  29. // return false;
  30. //}
  31. //unsigned short wPkgLen = sizeof(T_Msg) + 5;//包头字段长度为sizeof(WORD)(wPkgLen)+sizeof(BYTE)(byPkgType)+sizeof(WORD)(wCmd) = 5;
  32. //if ( wPkgLen >= PKGBUILD_BUF_SIZE )
  33. //{
  34. // nOutLen = 0;
  35. // *pOutPkg = NULL;
  36. // return false;
  37. //}
  38. //unsigned char byPkgType = T_Msg::byPkgType;
  39. //unsigned short wCmd = pPkg->wCmd;
  40. //memcpy( &(m_InnerBuf[0]), &wPkgLen, 2 );//包长:wPkgLen;
  41. //memcpy( &(m_InnerBuf[2]), &byPkgType, 1 );//包类型:byPkgType;
  42. //memcpy( &(m_InnerBuf[3]), &wCmd, 2 );//命令字:wCmd;
  43. //memcpy( &(m_InnerBuf[5]), pPkg, sizeof(T_Msg) );//包内容;
  44. //nOutLen = (int)wPkgLen;
  45. //*pOutPkg = (char*)m_InnerBuf;
  46. //return true;
  47. // 使用协议工具2008.7.15
  48. if ( pPkg->wCmd != T_Msg::wCmd )
  49. {
  50. nOutLen = 0;
  51. *pOutPkg = NULL;
  52. return false;
  53. }
  54. if (sizeof(T_Msg) > (PKGBUILD_BUF_SIZE - 5))
  55. {
  56. //D_ERROR( "CPacketBuild::CreatePkg,欲发包的包长超过了MsgToPut的内部缓存大小,包类型%x", T_Msg::wCmd );
  57. return NULL;
  58. }
  59. int iEnLen = (int)m_clipro.EnCode(pPkg->wCmd, pPkg, &(m_InnerBuf[5]), sizeof(m_InnerBuf) - 5);
  60. if(iEnLen == -1)
  61. {
  62. //D_ERROR( "CPacketBuild::CreatePkg,EnCode失败,包类型%x", T_Msg::wCmd );
  63. nOutLen = 0;
  64. *pOutPkg = NULL;
  65. return false;
  66. }
  67. unsigned char byPkgType = 0;
  68. unsigned short wCmd = pPkg->wCmd;
  69. unsigned short wPkgLen = iEnLen + 5;
  70. memcpy( &(m_InnerBuf[0]), &wPkgLen, 2 );//包长:wPkgLen;
  71. memcpy( &(m_InnerBuf[2]), &byPkgType, 1 );//包类型:byPkgType;
  72. memcpy( &(m_InnerBuf[3]), &wCmd, 2 );//命令字:wCmd;
  73. #ifdef CHECK_ENDIAN
  74. if ( g_isBigEndian )
  75. {
  76. unsigned short wLECmd = ENDIAN_CHANGE_S(wCmd);
  77. unsigned short wLEPkgLen = ENDIAN_CHANGE_S(wPkgLen);
  78. memcpy( &(m_InnerBuf[0]), &wLEPkgLen, 2 );//包长:wPkgLen;
  79. memcpy( &(m_InnerBuf[2]), &byPkgType, 1 );//包类型:byPkgType;
  80. memcpy( &(m_InnerBuf[3]), &wLECmd, 2 );//命令字:wCmd;
  81. }
  82. #endif //CHECK_ENDIAN
  83. nOutLen = (int)wPkgLen;
  84. *pOutPkg = (char*)m_InnerBuf;
  85. return true;
  86. };
  87. private:
  88. static char m_InnerBuf[PKGBUILD_BUF_SIZE];
  89. // 使用协议工具2008.7.15
  90. static CliProtocol m_clipro;
  91. };
  92. class CPacketBuildNetTrd //网络线程中组包类
  93. {
  94. public:
  95. //组包函数;
  96. template < typename T_Msg >
  97. bool CreateNetTrdPkg( T_Msg* pPkg, char** pOutPkg, int& nOutLen )
  98. {
  99. // 使用协议工具2008.7.15
  100. if ( pPkg->wCmd != T_Msg::wCmd )
  101. {
  102. nOutLen = 0;
  103. *pOutPkg = NULL;
  104. return false;
  105. }
  106. if (sizeof(T_Msg) > (PKGBUILD_BUF_SIZE - 5))
  107. {
  108. //D_ERROR( "CPacketBuild::CreatePkg,欲发包的包长超过了MsgToPut的内部缓存大小,包类型%x", T_Msg::wCmd );
  109. return NULL;
  110. }
  111. int iEnLen = (int)m_clipro.EnCode(pPkg->wCmd, pPkg, &(m_InnerBuf[5]), sizeof(m_InnerBuf) - 5);
  112. if(iEnLen == -1)
  113. {
  114. //D_ERROR( "CPacketBuild::CreatePkg,EnCode失败,包类型%x", T_Msg::wCmd );
  115. nOutLen = 0;
  116. *pOutPkg = NULL;
  117. return false;
  118. }
  119. unsigned char byPkgType = 0;
  120. unsigned short wCmd = pPkg->wCmd;
  121. unsigned short wPkgLen = iEnLen + 5;
  122. memcpy( &(m_InnerBuf[0]), &wPkgLen, 2 );//包长:wPkgLen;
  123. memcpy( &(m_InnerBuf[2]), &byPkgType, 1 );//包类型:byPkgType;
  124. memcpy( &(m_InnerBuf[3]), &wCmd, 2 );//命令字:wCmd;
  125. #ifdef CHECK_ENDIAN
  126. if ( g_isBigEndian )
  127. {
  128. unsigned short wLECmd = ENDIAN_CHANGE_S(wCmd);
  129. unsigned short wLEPkgLen = ENDIAN_CHANGE_S(wPkgLen);
  130. memcpy( &(m_InnerBuf[0]), &wLEPkgLen, 2 );//包长:wPkgLen;
  131. memcpy( &(m_InnerBuf[2]), &byPkgType, 1 );//包类型:byPkgType;
  132. memcpy( &(m_InnerBuf[3]), &wLECmd, 2 );//命令字:wCmd;
  133. }
  134. #endif //CHECK_ENDIAN
  135. nOutLen = (int)wPkgLen;
  136. *pOutPkg = (char*)m_InnerBuf;
  137. return true;
  138. };
  139. private:
  140. char m_InnerBuf[PKGBUILD_BUF_SIZE];
  141. CliProtocol m_clipro;
  142. };