コード例 #1
0
ファイル: DtmFileTransfer.cs プロジェクト: todoasap/CEX-NET
        private void ProcessAndPush(PacketBuffer Buffer, MemoryStream PacketStream)
        {
            int hdrLen = DtmPacketStruct.GetHeaderSize();
            int pktLen = 0;
            // get the header
            DtmPacketStruct pktHdr = new DtmPacketStruct(PacketStream);

            PacketStream.Seek(0, SeekOrigin.Begin);

            // track high sequence number
            if (pktHdr.Sequence > _seqCounter)
            {
                _seqCounter = pktHdr.Sequence;
            }

            // out of sync, possible packet loss
            if (_seqCounter - _rcvSequence > _bufferCount / 4)
            {
                // request a retransmission
                Transmit(DtmPacketFlags.Service, (short)DtmServiceFlags.Resend, _rcvSequence + 1);
            }

            // packet aligned
            if (pktHdr.PayloadLength + hdrLen == PacketStream.Length)
            {
                // resend was already processed
                if (pktHdr.Sequence < _rcvSequence)
                {
                    return;
                }

                // push onto buffer
                Buffer.Push(pktHdr.Sequence, PacketStream);
            }
            // more than one packet
            else if (pktHdr.PayloadLength + hdrLen < PacketStream.Length)
            {
                byte[] buffer;
                long   pos = 0;

                do
                {
                    // get packet position and size
                    pos = PacketStream.Position;

                    if (PacketStream.Length - pos < DtmPacketStruct.GetHeaderSize())
                    {
                        // next packet corrupted, request a retransmission and exit
                        Transmit(DtmPacketFlags.Service, (short)DtmServiceFlags.Resend, Buffer.GetHighKey() + 1);
                        return;
                    }

                    pktHdr = new DtmPacketStruct(PacketStream);
                    pktLen = (int)(hdrLen + pktHdr.PayloadLength);

                    if (pktLen > MAXRCVBUFFER || pktLen < 0 || PacketStream.Length - pos < pktLen)
                    {
                        // packet corrupted, request a retransmission and exit
                        Transmit(DtmPacketFlags.Service, (short)DtmServiceFlags.Resend, Buffer.GetHighKey() + 1);
                        return;
                    }
                    else
                    {
                        // create the buffer
                        buffer = new byte[pktLen];
                        PacketStream.Seek(pos, SeekOrigin.Begin);
                        PacketStream.Read(buffer, 0, (int)pktLen);
                        // push onto buffer
                        Buffer.Push(pktHdr.Sequence, new MemoryStream(buffer));
                    }
                } while (PacketStream.Position < PacketStream.Length);
            }
            // malformed packet, send retransmit request
            else if (pktHdr.PayloadLength > MAXRCVBUFFER || pktHdr.PayloadLength < 0 || pktHdr.PayloadLength + hdrLen > PacketStream.Length)
            {
                // packet corrupted, request a retransmission of last in queue + 1
                Transmit(DtmPacketFlags.Service, (short)DtmServiceFlags.Resend, Buffer.GetHighKey() + 1);
            }
        }