Beispiel #1
0
        public bool SendNextPacket()
        {
            NetPacket packet;

            lock (_outgoingPackets)
            {
                if (_outgoingPackets.Count == 0)
                {
                    return(false);
                }
                packet = _outgoingPackets.Dequeue();
            }
            _peer.SendRawData(packet);
            _peer.Recycle(packet);
            return(true);
        }
Beispiel #2
0
        //ProcessAck in packet
        public void ProcessAck(NetPacket packet)
        {
            int validPacketSize = (_windowSize - 1) / BitsInByte + 1 + NetConstants.SequencedHeaderSize;

            if (packet.Size != validPacketSize)
            {
                NetUtils.DebugWrite("[PA]Invalid acks packet size");
                return;
            }

            ushort ackWindowStart = packet.Sequence;

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

            //check relevance
            if (NetUtils.RelativeSequenceNumber(ackWindowStart, _localWindowStart) <= -_windowSize)
            {
                NetUtils.DebugWrite("[PA]Old acks");
                return;
            }

            byte[] acksData = packet.RawData;
            NetUtils.DebugWrite("[PA]AcksStart: {0}", ackWindowStart);
            int startByte = NetConstants.SequencedHeaderSize;

            Monitor.Enter(_pendingPackets);
            for (int i = 0; i < _windowSize; i++)
            {
                int ackSequence = (ackWindowStart + i) % NetConstants.MaxSequence;
                if (NetUtils.RelativeSequenceNumber(ackSequence, _localWindowStart) < 0)
                {
                    //NetUtils.DebugWrite(ConsoleColor.Cyan, "[PA] SKIP OLD: " + ackSequence);
                    //Skip old ack
                    continue;
                }

                int currentByte = startByte + i / BitsInByte;
                int currentBit  = i % BitsInByte;

                if ((acksData[currentByte] & (1 << currentBit)) == 0)
                {
                    //NetUtils.DebugWrite(ConsoleColor.Cyan, "[PA] SKIP FALSE: " + ackSequence);
                    //Skip false ack
                    continue;
                }

                if (ackSequence == _localWindowStart)
                {
                    //Move window
                    _localWindowStart = (_localWindowStart + 1) % NetConstants.MaxSequence;
                }

                NetPacket removed = _pendingPackets[ackSequence % _windowSize].GetAndClear();
                if (removed != null)
                {
                    _peer.Recycle(removed);

                    NetUtils.DebugWrite("[PA]Removing reliableInOrder ack: {0} - true", ackSequence);
                }
                else
                {
                    NetUtils.DebugWrite("[PA]Removing reliableInOrder ack: {0} - false", ackSequence);
                }
            }
            Monitor.Exit(_pendingPackets);
        }