Packet.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /*********************************************************************************
  2. *Author: OnClick
  3. *Version: 0.0.1
  4. *UnityVersion: 2017.2.3p3
  5. *Date: 2019-03-14
  6. *Description: IFramework
  7. *History: 2018.11--
  8. *********************************************************************************/
  9. using System;
  10. namespace IFramework.Packets
  11. {
  12. #pragma warning disable CS1591 // 缺少对公共可见类型或成员的 XML 注释
  13. public class Packet
  14. {
  15. private const int HelpBuffLen = 17;
  16. private static byte _packFlag = 0xfe;
  17. private static byte _subFlag = 0xfd;
  18. private PacketHeader _Head;
  19. public static byte packFlag
  20. {
  21. get { return _packFlag; }
  22. }
  23. public static byte subFlag
  24. {
  25. get { return _subFlag; }
  26. }
  27. public ushort pkgCount
  28. {
  29. get { return _Head.pkgCount; }
  30. }
  31. public byte pkgType
  32. {
  33. get { return _Head.pkgType; }
  34. }
  35. public UInt32 MainId
  36. {
  37. get { return _Head.MainId; }
  38. }
  39. public UInt32 SubId
  40. {
  41. get { return _Head.SubId; }
  42. }
  43. public byte[] message { get; private set; }
  44. public Packet()
  45. {
  46. _Head = new PacketHeader();
  47. }
  48. public Packet(ushort pkgCount, uint mainId, uint subId, byte pkgType, byte[] buffer) : this()
  49. {
  50. Config(pkgCount, mainId, subId, pkgType, buffer);
  51. }
  52. public void Config(ushort pkgCount, uint mainId, uint subId, byte pkgType, byte[] buffer)
  53. {
  54. _Head.pkgCount = pkgCount;
  55. _Head.MainId = mainId;
  56. _Head.SubId = subId;
  57. _Head.pkgType = pkgType;
  58. message = buffer;
  59. }
  60. public byte[] Pack()
  61. {
  62. int plen = message.Length;
  63. _Head.messageLen = (UInt32)plen;
  64. byte[] buffer = new byte[HelpBuffLen + plen];
  65. //int index = 0;
  66. buffer[0] = packFlag;
  67. buffer[1] = (byte)(_Head.MainId >> 24);//0
  68. buffer[2] = (byte)(_Head.MainId >> 16);
  69. buffer[3] = (byte)(_Head.MainId >> 8);
  70. buffer[4] = (byte)_Head.MainId;
  71. buffer[5] = (byte)(_Head.SubId >> 24);//4
  72. buffer[6] = (byte)(_Head.SubId >> 16);
  73. buffer[7] = (byte)(_Head.SubId >> 8);
  74. buffer[8] = (byte)_Head.SubId;
  75. buffer[9] = _Head.pkgType; //8
  76. buffer[10] = (byte)(_Head.pkgCount >> 8);//9
  77. buffer[11] = (byte)_Head.pkgCount;
  78. buffer[12] = (byte)(_Head.messageLen >> 24);//11
  79. buffer[13] = (byte)(_Head.messageLen >> 16);
  80. buffer[14] = (byte)(_Head.messageLen >> 8);
  81. buffer[15] = (byte)(_Head.messageLen);
  82. Buffer.BlockCopy(message, 0, buffer, HelpBuffLen - 1, plen);
  83. buffer[buffer.Length - 1] = packFlag;
  84. return Escape(buffer);
  85. }
  86. private unsafe byte[] Escape(byte[] buffer)
  87. {
  88. int pktCnt = 0, subCnt = 0;
  89. /*var tCnt = */
  90. CheckEscapeFlagCount(buffer, out pktCnt, out subCnt);
  91. if ( /*(tCnt.Item1 + tCnt.Item2) == 0*/ pktCnt + subCnt == 0) return buffer;
  92. int plen = buffer.Length - 2;
  93. byte[] rBuffer = new byte[buffer.Length + pktCnt + subCnt /*tCnt.Item1 + tCnt.Item2*/];
  94. rBuffer[0] = buffer[0]; //起始标识位
  95. fixed (byte* dst = &(rBuffer[1]), src = &(buffer[1]))
  96. {
  97. byte* _dst = dst;
  98. byte* _src = src;
  99. //消息头和消息体
  100. while (plen > 0)
  101. {
  102. if (*_src == packFlag)
  103. {
  104. *_dst = subFlag;
  105. *(_dst + 1) = 0x01;
  106. _dst += 2;
  107. }
  108. else if (*_src == subFlag)
  109. {
  110. *_dst = subFlag;
  111. *(_dst + 1) = 0x02;
  112. _dst += 2;
  113. }
  114. else
  115. {
  116. *_dst = *_src;
  117. _dst += 1;
  118. }
  119. _src += 1;
  120. plen -= 1;
  121. }
  122. //结束标志位
  123. *_dst = *_src;
  124. return rBuffer;
  125. }
  126. }
  127. private unsafe void CheckEscapeFlagCount(byte[] buffer, out int pktCnt, out int subCnt)
  128. {
  129. int len = buffer.Length - 2; //去头尾标识位
  130. /* int*/
  131. pktCnt = 0; /*,*/
  132. subCnt = 0;
  133. fixed (byte* src = &(buffer[1]))
  134. {
  135. byte* _src = src;
  136. do
  137. {
  138. if (*_src == packFlag)
  139. {
  140. ++pktCnt;
  141. }
  142. else if (*_src == subFlag)
  143. {
  144. ++subCnt;
  145. }
  146. _src += 1;
  147. --len;
  148. } while (len > 0);
  149. }
  150. // return Tuple.Create(pktCnt, subCnt);
  151. }
  152. public static Packet UnPackPacket(byte[] buffer, int offset, int size)
  153. {
  154. if (buffer.Length < HelpBuffLen || buffer.Length < (offset + size))
  155. return null; // throw new Exception("{61573C82-F128-4ADE-A6AA-88004EB0EBBE}:有效字节长度过短");
  156. //还原转义并且过滤标志位,9为去掉标识位的head长度
  157. byte[] dst = Restore(buffer, offset, size);
  158. if (dst.Length < HelpBuffLen - 2) return null;
  159. //throw new Exception("{4DE7D881-0C40-4C09-8337-CE06CC2761FF}:转义还原数组溢出"+dst.Length);
  160. //uint plen = dst.ToUInt32(7);
  161. uint plen = dst.ToUInt32(11);
  162. if (plen > dst.Length - HelpBuffLen + 2) return null;
  163. Packet p = new Packet();
  164. p._Head = new PacketHeader();
  165. p._Head.MainId = dst.ToUInt32(0);
  166. p._Head.SubId = dst.ToUInt32(4);
  167. p._Head.pkgType = dst[8];
  168. p._Head.pkgCount = dst.ToUInt16(9);
  169. p._Head.messageLen = plen;
  170. p.message = new byte[p._Head.messageLen];
  171. Buffer.BlockCopy(dst, HelpBuffLen - 2, p.message, 0, p.message.Length);
  172. return p;
  173. }
  174. private static unsafe byte[] Restore(byte[] buffer, int offset, int size)
  175. {
  176. int pkgCnt = 0, subCnt = 0;
  177. /*var tCnt =*/
  178. CheckRestoreFlagCount(buffer, offset, size, out pkgCnt, out subCnt);
  179. if ( /*(tCnt.Item1 + tCnt.Item2)*/pkgCnt + subCnt == 0)
  180. {
  181. byte[] buff = new byte[size - 2];
  182. if (buffer.Length < offset + 1 + buff.Length)
  183. throw new Exception("{FE815CC3-EA7D-49BF-89ED-E1B63D812D4F}:偏移长度溢出");
  184. Buffer.BlockCopy(buffer, offset + 1, buff, 0, buff.Length);
  185. return buff;
  186. }
  187. int pLen = size - 2; //去掉标志位后的长度
  188. byte[] rBuffer = new byte[pLen - pkgCnt - subCnt /*tCnt.Item1 - tCnt.Item2*/];
  189. fixed (byte* dst = rBuffer, src = &(buffer[offset + 1]))
  190. {
  191. byte* _src = src;
  192. byte* _dst = dst;
  193. //开始标志位
  194. //*(dst+0) = *(src + offset);
  195. //消息头和消息体
  196. while (pLen >= 0)
  197. {
  198. if (*(_src) == subFlag && *(_src + 1) == 0x01)
  199. {
  200. *(_dst) = packFlag;
  201. _src += 2;
  202. _dst += 1;
  203. pLen -= 2;
  204. }
  205. else if (*(_src) == subFlag && *(_src + 1) == 0x02)
  206. {
  207. *(_dst) = subFlag;
  208. _src += 2;
  209. _dst += 1;
  210. pLen -= 2;
  211. }
  212. else
  213. {
  214. *(_dst) = *(_src);
  215. _src += 1;
  216. _dst += 1;
  217. pLen -= 1;
  218. }
  219. }
  220. return rBuffer;
  221. }
  222. }
  223. private static unsafe void CheckRestoreFlagCount(byte[] buffer, int offset, int size, out int pkgCnt, out int subCnt)
  224. {
  225. int len = size - 2;
  226. //int i = offset + 1;
  227. //int pkgCnt = 0, subCnt = 0;
  228. pkgCnt = subCnt = 0;
  229. fixed (byte* src = &(buffer[offset + 1]))
  230. {
  231. byte* _src = src;
  232. do
  233. {
  234. if (*_src == subFlag && *(_src + 1) == 0x01)
  235. {
  236. ++pkgCnt;
  237. _src += 2;
  238. len -= 2;
  239. }
  240. else if (*_src == subFlag && *(_src + 1) == 0x02)
  241. {
  242. ++subCnt;
  243. _src += 2;
  244. len -= 2;
  245. }
  246. else
  247. {
  248. _src += 1;
  249. --len;
  250. }
  251. } while (len > 0);
  252. }
  253. //return Tuple.Create(pkgCnt, subCnt);
  254. }
  255. }
  256. #pragma warning restore CS1591 // 缺少对公共可见类型或成员的 XML 注释
  257. }