예제 #1
0
        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);
        }
예제 #2
0
 /// <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);
 }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
 public abstract void Receive(_RawPacket packet);