BytesReader.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. using System;
  2. namespace XGame.Framework.Network
  3. {
  4. public class BytesReader : IBytesReader
  5. {
  6. private enum ReadState
  7. {
  8. readHead = 0,
  9. readBody = 1,
  10. closed = 2
  11. }
  12. private const int BUFFER_SIZE = ushort.MaxValue;
  13. //private const int Length_Heart = 2;
  14. //private const int Length_Response = 10;//modify
  15. //private const int Length_Push = 6;
  16. private ReadState _readState = ReadState.readHead;
  17. private int _bytesOffset = 0;
  18. private byte[] _recvBytes = new byte[BUFFER_SIZE];
  19. private int _msgLength = 0;
  20. private int _headLength = 0;
  21. public IMsgReceiver _receiver;
  22. public BytesReader(IMsgReceiver receiver)
  23. {
  24. _receiver = receiver;
  25. }
  26. public void Read(byte[] bytes, int offset, int length)
  27. {
  28. while (offset <= length)
  29. {
  30. if (_readState == ReadState.readHead)
  31. {
  32. int len = length - offset;//数据长度
  33. if ((_bytesOffset == 0 && len >= 2) || _bytesOffset == 1)//需要知道头部长度的情况
  34. {
  35. _headLength = GetHeadLen(bytes[_bytesOffset == 0 ? 1 + offset : 0 + offset]);
  36. if (_headLength != NetDefine.HEAD_LENGTH_PUSH && _headLength != NetDefine.HEAD_LENGTH_REQUEST && _headLength != NetDefine.HEAD_LENGTH_HEART)
  37. {
  38. Log.Error($"[Net] 消息Head长度错误,HeadLength={_headLength}");
  39. Reset();
  40. return;
  41. }
  42. }
  43. //只有知道头部长度才知道是否完整
  44. if (_headLength != 0 && len >= _headLength - _bytesOffset)//说明头部完整
  45. {
  46. WriteBytes(bytes, offset, _recvBytes, _bytesOffset, _headLength - _bytesOffset);
  47. _readState = ReadState.readBody;
  48. offset += _headLength - _bytesOffset;
  49. _bytesOffset = _headLength;
  50. if (_headLength != NetDefine.HEAD_LENGTH_HEART)
  51. {
  52. _msgLength = GetMsgLen(_bytesOffset, _recvBytes);//获取消息长度
  53. }
  54. if (offset <= length)
  55. {
  56. //还有数据就接着读
  57. continue;
  58. }
  59. }
  60. else
  61. {
  62. //能走到这里说明头部不完整 先把byte记下 等下一条
  63. WriteBytes(bytes, offset, _recvBytes, _bytesOffset, len);
  64. _bytesOffset += len;
  65. }
  66. return;
  67. }
  68. else if (_readState == ReadState.readBody)
  69. {
  70. int len = length - offset;
  71. if (len >= _msgLength + _headLength - _bytesOffset)//body完整
  72. {
  73. int realLength = _msgLength + _headLength - _bytesOffset;
  74. WriteBytes(bytes, offset, _recvBytes, _bytesOffset, realLength);//全部写入
  75. offset += _msgLength + _headLength - _bytesOffset;
  76. _receiver.Receive(_recvBytes, _headLength, _msgLength);//开始解析
  77. Reset();
  78. if (offset < length)//后面接了下一条消息
  79. {
  80. continue;
  81. }
  82. }
  83. else
  84. {
  85. //能走到这里说明body不完整 先把byte记下 等下一条
  86. WriteBytes(bytes, offset, _recvBytes, _bytesOffset, len);
  87. _bytesOffset += len;
  88. _readState = ReadState.readBody;
  89. }
  90. return;
  91. }
  92. }
  93. }
  94. private int GetMsgLen(int offset, byte[] bytes)
  95. {
  96. return (bytes[offset - 2] << 8) + bytes[offset - 1];
  97. }
  98. private int GetHeadLen(byte _byte)
  99. {
  100. int type = _byte >> 6;
  101. int len = 0;
  102. switch ((MsgType)type)
  103. {
  104. case MsgType.PUSH:
  105. len = NetDefine.HEAD_LENGTH_PUSH;
  106. break;
  107. case MsgType.RESPONSE:
  108. len = NetDefine.HEAD_LENGTH_REQUEST;
  109. break;
  110. case MsgType.HEART_BEAT:
  111. len = NetDefine.HEAD_LENGTH_HEART;
  112. break;
  113. case MsgType.REQUEST:
  114. Log.Error($"[Net] MsgType搞错啦!!不是Request! 请确认服务器的地址和端口是否正确!");
  115. break;
  116. default:
  117. Log.Error($"[Net] MsgType未知的一条消息 type:{type} 请确认服务器的地址和端口是否正确!");
  118. break;
  119. }
  120. return len;
  121. }
  122. private void WriteBytes(byte[] source, int sourceOffset, byte[] target, int targetOffset, int length)
  123. {
  124. Array.Copy(source, sourceOffset, target, targetOffset, length);
  125. }
  126. public void Reset()
  127. {
  128. _bytesOffset = 0;
  129. _headLength = 0;
  130. _msgLength = 0;
  131. if (_readState != ReadState.closed)
  132. _readState = ReadState.readHead;
  133. }
  134. }
  135. }