private static _RawPacket _TryAssembly(SortedList <_SubPacketHead, byte[]> subPackets) { // 若子包序列已经收齐,则组装后返回 var firstHead = subPackets.First().Key; if (firstHead.PacketType != EPacketType.UdpLargeFirst || firstHead.sub != subPackets.Count) { return(null); } var dataList = subPackets.Values; var length = (int)BitConverter.ToUInt32(dataList[0], 0); if (length != dataList.Sum(bytes => bytes.Length)) { throw new InvalidDataException("Packet length check failed"); } var retPacket = new _RawPacket { code = BitConverter.ToUInt16(dataList[0], 4), timestamp = _ExpandTimestamp(BitConverter.ToUInt32(dataList[0], 6)), data = new byte[length - HEAD_LENGTH] }; var buffStream = new MemoryStream(retPacket.data); buffStream.Write(dataList[0], HEAD_LENGTH, dataList[0].Length - HEAD_LENGTH); for (var i = 1; i < dataList.Count; ++i) { buffStream.Write(dataList[i], 0, dataList[i].Length); } return(retPacket); }
/// <summary> /// 转发数据包至所有绑定的接收者。 /// </summary> /// <param name="packet">数据包</param> /// <seealso cref="BindReceiver{T}"/> internal void ForwardPacket(_RawPacket packet) { if (!_handlers.TryGetValue(packet.GetType(), out var receivers)) { ULogger.Warning($"{packet.GetType ().FullName} has not been set in protocal"); return; } receivers?.Receive(packet); }
private int _ReadHeadAndCreateBuff(BinaryReader reader) { var head = ReadFrom(reader); if (head.PacketType != EPacketType.Tcp) { throw new InvalidDataException("Received packet is not TCP type"); } var data = new byte[(int)reader.ReadUInt32()]; _buffStream = new MemoryStream(data); _currentReadingPacket = new _RawPacket { code = reader.ReadUInt16(), timestamp = _ExpandTimestamp(reader.ReadUInt32()), data = data }; return(Size(head.PacketType) + HEAD_LENGTH); }
public override _RawPacket Read(BinaryReader reader, int avaliableBytes) { var subPacketHead = ReadFrom(reader); avaliableBytes -= Size(subPacketHead.PacketType); if (subPacketHead.PacketType == EPacketType.Tcp) { throw new InvalidDataException("Received packet is not UDP type"); } _RawPacket retPacket; if (subPacketHead.PacketType == EPacketType.UdpSmall) { int length = reader.ReadUInt16(); if (length != avaliableBytes) { throw new InvalidDataException("Packet length check failed"); } retPacket = new _RawPacket { code = reader.ReadUInt16(), timestamp = _ExpandTimestamp(reader.ReadUInt32()), data = reader.ReadBytes(avaliableBytes - SMALL_HEAD_LENGTH) }; return(retPacket); } // 读取并添加子包 var subPacketData = reader.ReadBytes(avaliableBytes); _AddSubPacket(subPacketHead, subPacketData); // 检查并尝试装配子包序列 retPacket = _TryAssembly(_subPackets[subPacketHead.seq]); if (retPacket != null) { _subPackets[subPacketHead.seq] = null; } return(retPacket); }
public override _RawPacket Read(BinaryReader reader, int avaliableBytes) { if (_buffStream == null) { if (avaliableBytes < Size(EPacketType.Tcp) + HEAD_LENGTH) { return(null); } avaliableBytes -= _ReadHeadAndCreateBuff(reader); } var bytesToRead = Math.Min(_buffStream.Capacity - (int)_buffStream.Position, avaliableBytes); _buffStream.Write(reader.ReadBytes(bytesToRead), 0, bytesToRead); if (_buffStream.Position != _buffStream.Capacity) { return(null); } var retPacket = _currentReadingPacket; _buffStream = null; _currentReadingPacket = null; return(retPacket); }
public abstract void Receive(_RawPacket packet);