Пример #1
0
        public void SendNextPackets()
        {
            //Monitor.Enter(_pendingPackets);
            //get packets from queue
            Monitor.Enter(_outgoingPackets);

            int relate = _headPendingPacket == null ? -1 : _headPendingPacket.idx - 1;

            if (relate < 0)
            {
                relate += _windowSize;
            }

            PendingPacket tailPendingPacket = _headPendingPacket;

            while (tailPendingPacket != null && tailPendingPacket.Next != null)
            {
                tailPendingPacket = tailPendingPacket.Next;
            }
            int packetUsed = 0;
            int nextPacket = tailPendingPacket == null ? 0 : tailPendingPacket.idx + 1;

            foreach (NetPacket packet in _outgoingPackets)
            {
                if (tailPendingPacket == null || tailPendingPacket.idx == relate)
                {
                    PendingPacket pendingPacket = _pendingPackets[nextPacket++ % _windowSize];
                    pendingPacket.Packet = packet;
                    packetUsed++;
                    pendingPacket.Packet.Sequence = (ushort)_localSequence;
                    if (_headPendingPacket == null)
                    {
                        _headPendingPacket = pendingPacket;
                    }
                    if (tailPendingPacket != null)
                    {
                        tailPendingPacket.Next = pendingPacket;
                    }
                    tailPendingPacket = pendingPacket;
                    _localSequence    = NetUtils.IncrementSequenceNumber(_localSequence, 1);
                }
                else //Queue filled
                {
                    break;
                }
            }
            _outgoingPackets.RemoveRange(0, packetUsed);

            Monitor.Exit(_outgoingPackets);

            ResendPackets();
        }
Пример #2
0
        //ProcessAck in packet
        public void ProcessAck(NetPacket packet)
        {
            ushort ackWindowStart = packet.Sequence;

            if (ackWindowStart >= NetConstants.MaxSequence)
            {
                NetUtils.DebugWrite("[PA]Bad window start");
                return;
            }

            byte[] acksData = packet.RawData;
            NetUtils.DebugWrite("[PA]AcksStart: {0}", ackWindowStart);
            //Monitor.Enter(_pendingPackets);

            for (int idx = 0; idx < packet.GetDataSize(); ++idx)
            {
                int currentByte = idx / BitsInByte;
                int currentBit  = idx % BitsInByte;
                if ((acksData[currentByte] & (1 << currentBit)) == 0)
                {
                    // Packet not ack, will be resent automaticaly as needed
                    continue;
                }

                // packet acknowledged = true
                int seqAck = NetUtils.IncrementSequenceNumber(ackWindowStart, idx);

                PendingPacket pendingPacket = _headPendingPacket;
                PendingPacket prevPacket    = null;
                while (pendingPacket != null)
                {
                    // Looking for the packet to acknowledge
                    if (pendingPacket.Packet.Sequence != seqAck)
                    {
                        prevPacket    = pendingPacket;
                        pendingPacket = pendingPacket.Next;
                        continue;
                    }

                    // Packet found, remove it from the list
                    if (pendingPacket == _headPendingPacket)
                    {
                        _headPendingPacket = pendingPacket.Next;
                    }

                    var packetToClear = pendingPacket;

                    //move forward
                    pendingPacket = pendingPacket.Next;
                    if (prevPacket != null)
                    {
                        prevPacket.Next = pendingPacket;
                    }

                    //clear acked packet
                    packetToClear.Packet.Recycle();
                    packetToClear.Clear();
                    NetUtils.DebugWrite("[PA]Removing reliableInOrder ack: {0} - true", seqAck);
                    break;
                }
            }
            //Monitor.Exit(_pendingPackets);
        }
Пример #3
0
        //Process incoming packet
        public bool ProcessPacket(NetPacket packet)
        {
            if (_mustSendAcksStartTimer <= 0)
            {
                _mustSendAcksStartTimer = NetTime.NowMs;
            }

            if (packet.Sequence >= NetConstants.MaxSequence)
            {
                NetUtils.DebugWrite("[RR]Bad sequence");
                return(false);
            }

            _packetsToAcknowledge.Add(packet.Sequence);

            // Check if its a duplicated packet
            if (_ordered && RelativeSequenceDiff(packet.Sequence, _remoteSequence) < 0)
            {
                // Its a duplicated packet
                return(false);
            }

            //detailed check
            if (packet.Sequence == _remoteSequence)
            {
                NetUtils.DebugWrite("[RR]ReliableInOrder packet succes");
                _peer.AddIncomingPacket(packet);
                _remoteSequence = NetUtils.IncrementSequenceNumber(_remoteSequence, 1);

                if (_ordered)
                {
                    NetPacket p;
                    while ((p = _receivedPackets[_remoteSequence % _windowSize]) != null)
                    {
                        //process holded packet
                        _receivedPackets[_remoteSequence % _windowSize] = null;
                        _peer.AddIncomingPacket(p);
                        _remoteSequence = NetUtils.IncrementSequenceNumber(_remoteSequence, 1);
                    }
                }
                else
                {
                    while (_earlyReceived[_remoteSequence % _windowSize])
                    {
                        //process early packet
                        _earlyReceived[_remoteSequence % _windowSize] = false;
                        _remoteSequence = NetUtils.IncrementSequenceNumber(_remoteSequence, 1);
                    }
                }

                return(true);
            }

            //holded packet
            if (_ordered)
            {
                // Doesnt matter if it overwrites multiple time the same packet
                _receivedPackets[packet.Sequence % _windowSize] = packet;
            }
            else
            {
                if (_earlyReceived[packet.Sequence % _windowSize] == false)
                {
                    _earlyReceived[packet.Sequence % _windowSize] = true;
                    _peer.AddIncomingPacket(packet);
                }
            }

            return(true);
        }