/// <summary> /// 解包协议数据 /// </summary> /// <param name="buffer"></param> /// <returns>使用的数据长度</returns> public int Unpack(byte[] buffer, int available, Action <byte[]> onReceiveData) { ByteArray ba = new ByteArray(buffer, available); int used = 0; while (ba.ReadEnableSize > ByteArray.USHORT_SIZE) { //获取协议数据长度 ushort protocolSize = ba.ReadUShort(); if (ba.ReadEnableSize >= protocolSize) { byte[] protocolData = ba.ReadBytes(protocolSize); onReceiveData?.Invoke(protocolData); //记录使用协议长度 used += ByteArray.USHORT_SIZE + protocolData.Length; } } return(used); }
void Unpack(ByteArray ba, ref int used, Action <EOpcode, byte[]> onReceiveData) { if (ba.ReadEnableSize < 2 * ByteArray.BYTE_SIZE) { //数据存在半包问题 return; } int startPos = ba.Pos; //获取第一个byte byte byte1 = ba.ReadByte(); bool fin = (byte1 & 128) == 128 ? true : false; var rsv123 = (byte1 & 112); var opcode = (EOpcode)(byte1 & 15); //获取第二个byte byte byte2 = ba.ReadByte(); bool mask = (byte2 & 128) == 128 ? true : false; var payloadLen = (byte2 & 127); int dataSize = 0; switch (payloadLen) { case 127: if (ba.ReadEnableSize < 2 * ByteArray.ULONG_SIZE) { //数据存在半包问题 return; } dataSize = (int)ba.ReadULong(); break; case 126: if (ba.ReadEnableSize < 2 * ByteArray.USHORT_SIZE) { //数据存在半包问题 return; } dataSize = ba.ReadUShort(); break; default: dataSize = payloadLen; break; } byte[] maskKeys = null; if (mask) { if (ba.ReadEnableSize < 4 * ByteArray.BYTE_SIZE) { //数据存在半包问题 return; } maskKeys = new byte[4]; for (int i = 0; i < maskKeys.Length; i++) { maskKeys[i] = ba.ReadByte(); } } switch (opcode) { case EOpcode.CONTINUE: case EOpcode.PING: case EOpcode.PONG: case EOpcode.CLOSE: //使用率低,暂不处理这种情况 onReceiveData?.Invoke(opcode, null); break; case EOpcode.TEXT: case EOpcode.BYTE: if (dataSize > 0) { if (ba.ReadEnableSize < dataSize) { //数据存在半包问题 return; } byte[] payloadData = ba.ReadBytes(dataSize); if (mask) { for (int i = 0; i < payloadData.Length; i++) { var maskKey = maskKeys[i % 4]; payloadData[i] = (byte)(payloadData[i] ^ maskKey); } } onReceiveData?.Invoke(opcode, payloadData); } break; default: Log.E(string.Format("不可识别的WS协议:{0}", opcode)); return; } used += ba.Pos - startPos; Unpack(ba, ref used, onReceiveData); }