Exemple #1
0
        public ReliableChannel(NetPeer peer, bool ordered)
        {
            _windowSize = NetConstants.DefaultWindowSize;
            _peer       = peer;
            _ordered    = ordered;

            _outgoingPackets = new Queue <NetPacket>(_windowSize);
            _pendingPackets  = new PendingPacket[_windowSize];
            for (int i = 0; i < _pendingPackets.Length; i++)
            {
                _pendingPackets[i] = new PendingPacket();
            }

            if (_ordered)
            {
                _receivedPackets = new NetPacket[_windowSize];
            }
            else
            {
                _earlyReceived = new bool[_windowSize];
            }

            _localWindowStart  = 0;
            _localSeqence      = 0;
            _remoteSequence    = 0;
            _remoteWindowStart = 0;

            //Init acks packet
            int            bytesCount = (_windowSize - 1) / BitsInByte + 1;
            PacketProperty property   = _ordered ? PacketProperty.AckReliableOrdered : PacketProperty.AckReliable;

            _outgoingAcks = _peer.GetPacketFromPool(property, bytesCount);
        }
        public void SendNextPackets()
        {
            //Monitor.Enter(_pendingPackets);
            //get packets from queue
            //Monitor.Enter(_outgoingPackets);

            while (_outgoingPackets.Empty == false)
            {
                if (_headPendingPacket.Next != _tailPendingPacket)
                {
                    NetPacket     packet        = _outgoingPackets.Dequeue();
                    PendingPacket pendingPacket = _headPendingPacket;
                    pendingPacket.Packet = packet;
                    _localSequence       = (_localSequence + 1); // % NetConstants.MaxSequence;
                    if (_localSequence == NetConstants.MaxSequence)
                    {
                        _localSequence = 0;
                    }
                    pendingPacket.Packet.Sequence = (ushort)_localSequence;
                    _headPendingPacket            = _headPendingPacket.Next;
                }
                else //Queue filled
                {
                    break;
                }
            }
            //_outgoingPackets.RemoveRange(0, packetUsed);

            //Monitor.Exit(_outgoingPackets);

            ResendPackets();
        }
        public virtual PendingPacket QueueIncomingPacket(EndPoint endPoint, Packet packet)
        {
            var pendingPacket = PendingPacket.FromPacket(endPoint, packet);

            incoming.Enqueue(pendingPacket);
            return(pendingPacket);
        }
Exemple #4
0
        public override void SendNextPackets()
        {
            //check sending acks
            if (_mustSendAcks)
            {
                _mustSendAcks = false;
                NetUtils.DebugWrite("[RR]SendAcks");
                Monitor.Enter(_outgoingAcks);
                Peer.SendRawData(_outgoingAcks);
                Monitor.Exit(_outgoingAcks);
            }

            long currentTime = DateTime.UtcNow.Ticks;

            Monitor.Enter(_pendingPackets);
            //get packets from queue
            Monitor.Enter(OutgoingQueue);
            while (OutgoingQueue.Count > 0)
            {
                int relate = NetUtils.RelativeSequenceNumber(_localSeqence, _localWindowStart);
                if (relate < _windowSize)
                {
                    PendingPacket pendingPacket = _pendingPackets[_localSeqence % _windowSize];
                    pendingPacket.Sended          = false;
                    pendingPacket.Packet          = OutgoingQueue.Dequeue();
                    pendingPacket.Packet.Sequence = (ushort)_localSeqence;
                    _localSeqence = (_localSeqence + 1) % NetConstants.MaxSequence;
                }
                else //Queue filled
                {
                    break;
                }
            }
            Monitor.Exit(OutgoingQueue);
            //send
            double resendDelay = Peer.ResendDelay;

            for (int pendingSeq = _localWindowStart; pendingSeq != _localSeqence; pendingSeq = (pendingSeq + 1) % NetConstants.MaxSequence)
            {
                PendingPacket currentPacket = _pendingPackets[pendingSeq % _windowSize];
                if (currentPacket.Packet == null)
                {
                    continue;
                }
                if (currentPacket.Sended) //check send time
                {
                    double packetHoldTime = currentTime - currentPacket.TimeStamp;
                    if (packetHoldTime < resendDelay * TimeSpan.TicksPerMillisecond)
                    {
                        continue;
                    }
                    NetUtils.DebugWrite("[RC]Resend: {0} > {1}", (int)packetHoldTime, resendDelay);
                }

                currentPacket.TimeStamp = currentTime;
                currentPacket.Sended    = true;
                Peer.SendRawData(currentPacket.Packet);
            }
            Monitor.Exit(_pendingPackets);
        }
Exemple #5
0
        PendingPacket ExpirePendingPacket(int time)
        {
            byte          id     = 0;
            PendingPacket packet = new PendingPacket();

            lock (m_pendingPackets)
            {
                if (m_pendingPackets.Count > 0)
                {
                    if ((time - m_pendingPackets[0].TimeStamp) > m_timerInterval)
                    {
                        packet        = m_pendingPackets[0];
                        id            = packet.Cookie;
                        packet.Cookie = 0;
                        m_pendingPackets.RemoveAt(0);
                    }
                }
            }
            if (id != 0)
            {
                lock (m_availableIds)
                {
                    m_availableIds.Enqueue(id);
                }
            }
            return(packet);
        }
Exemple #6
0
        public ReliableChannel(NetPeer peer, bool ordered, byte id) : base(peer)
        {
            _id             = id;
            _windowSize     = NetConstants.DefaultWindowSize;
            _ordered        = ordered;
            _pendingPackets = new PendingPacket[_windowSize];
            for (int i = 0; i < _pendingPackets.Length; i++)
            {
                _pendingPackets[i] = new PendingPacket();
            }

            if (_ordered)
            {
                _deliveryMethod  = DeliveryMethod.ReliableOrdered;
                _receivedPackets = new NetPacket[_windowSize];
            }
            else
            {
                _deliveryMethod = DeliveryMethod.ReliableUnordered;
                _earlyReceived  = new bool[_windowSize];
            }

            _localWindowStart  = 0;
            _localSeqence      = 0;
            _remoteSequence    = 0;
            _remoteWindowStart = 0;
            _outgoingAcks      = new NetPacket(PacketProperty.Ack, (_windowSize - 1) / BitsInByte + 2)
            {
                ChannelId = id
            };
        }
Exemple #7
0
        void TimeoutEvent(object state)
        {
            while (true)
            {
                PendingPacket packet = ExpirePendingPacket(Environment.TickCount);
                if (packet.Packet != null)
                {
                    if (packet.Attempt >= m_retryMax)
                    {
                        m_dispatcher.NotifySendFailure(this, packet.Packet);
                    }
                    else
                    {
                        lock (m_resendPackets)
                        {
                            m_resendPackets.Add(packet);
                        }
                    }
                }
                else
                {
                    break;
                }
            }

            PumpResend();
        }
Exemple #8
0
        PendingPacket RetirePendingPacket(byte id)
        {
            bool          found  = false;
            PendingPacket packet = new PendingPacket();

            lock (m_pendingPackets)
            {
                for (int pInd = 0, count = m_pendingPackets.Count; pInd < count; ++pInd)
                {
                    if (m_pendingPackets[pInd].Cookie == id)
                    {
                        packet        = m_pendingPackets[pInd];
                        packet.Cookie = 0;
                        m_pendingPackets.RemoveAt(pInd);
                        found = true;
                        break;
                    }
                }
            }
            if (found)
            {
                lock (m_availableIds)
                {
                    m_availableIds.Enqueue(id);
                }
            }
            return(packet);
        }
        public ReliableChannel(NetPeer peer, bool ordered, int windowSize)
        {
            _resendDelay = peer.Handler.ReliableResendTime;
            _windowSize = windowSize;
            _peer = peer;
            _ordered = ordered;

            _outgoingPackets = new Queue<NetPacket>(_windowSize);

            _outgoingAcks = new bool[_windowSize];
            _pendingPackets = new PendingPacket[_windowSize];
            for (int i = 0; i < _pendingPackets.Length; i++)
            {
                _pendingPackets[i] = new PendingPacket();
            }

            if (_ordered)
                _receivedPackets = new NetPacket[_windowSize];
            else
                _earlyReceived = new bool[_windowSize];

            _localWindowStart = 0;
            _localSeqence = 0;
            _remoteSequence = 0;
            _remoteWindowStart = 0;
        }
        public ReliableChannel(NetPeer peer, bool ordered, int windowSize)
        {
            _windowSize = windowSize;
            _peer       = peer;
            _ordered    = ordered;

            _outgoingPackets = new Queue <NetPacket>(_windowSize);

            _outgoingAcks   = new bool[_windowSize];
            _pendingPackets = new PendingPacket[_windowSize];
            for (var i = 0; i < _pendingPackets.Length; i++)
            {
                _pendingPackets[i] = new PendingPacket();
            }

            if (_ordered)
            {
                _receivedPackets = new NetPacket[_windowSize];
            }
            else
            {
                _earlyReceived = new bool[_windowSize];
            }

            _localWindowStart  = 0;
            _localSeqence      = 0;
            _remoteSequence    = 0;
            _remoteWindowStart = 0;
        }
Exemple #11
0
        public void EnqueuePacketForProcessing(byte[] rawData, object userData)
        {
#if DEBUG
            if (SimulateLatency)
            {
                lock (delayedPackets)
                {
                    PendingPacket packet  = new PendingPacket(rawData, userData);
                    DateTime      dueTime = DateTime.UtcNow.AddMilliseconds(simulationRandom.Next(SimulatedMinLatency, SimulatedMaxLatency));
                    delayedPackets.Add(new DelayedPacket(packet, dueTime));
                }
            }
            else
            {
                lock (pendingPackets)
                {
                    pendingPackets.Enqueue(new PendingPacket(rawData, userData));
                }
            }
#else
            lock (pendingPackets)
            {
                pendingPackets.Enqueue(new PendingPacket(rawData, userData));
            }
#endif
        }
        public virtual PendingPacket QueueOutgoingPacket(EndPoint endPoint, Packet packet)
        {
            var pendingPacket = PendingPacket.FromPacket(endPoint, packet, incoming: false);

            outgoing.Enqueue(pendingPacket);
            return(pendingPacket);
        }
        public ReliableChannel(NetPeer peer, bool ordered, int channel)
        {
            _windowSize = NetConstants.DefaultWindowSize;
            _peer       = peer;
            _ordered    = ordered;
            _channel    = channel;

            _outgoingPackets = new List <NetPacket>(_windowSize);
            _pendingPackets  = new PendingPacket[_windowSize];
            for (int i = 0; i < _pendingPackets.Length; i++)
            {
                _pendingPackets[i]     = new PendingPacket();
                _pendingPackets[i].idx = i;
            }

            if (_ordered)
            {
                _receivedPackets = new NetPacket[_windowSize];
            }
            else
            {
                _earlyReceived = new bool[_windowSize];
            }

            _localSequence        = 0;
            _remoteSequence       = 0;
            _packetsToAcknowledge = new List <ushort>();

            _mustSendAcksStartTimer = -1;

            //Init acks packet
            PacketProperty property = _ordered ? PacketProperty.AckReliableOrdered : PacketProperty.AckReliable;

            _outgoingAcks = _peer.GetPacketFromPool(property, channel, NetConstants.MinPacketDataSize);
        }
Exemple #14
0
 public void Clear()
 {
     Next    = null;
     Packet  = null;
     Sended  = false;
     Resends = 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 i = 0; i < packet.GetDataSize(); ++i)
            {
                byte acksByte = acksData[i];
                for (int idx = 0; idx < 8; ++idx)
                {
                    if ((acksByte & (1 << idx)) == 0)
                    {
                        // Packet not ack, will be resent automaticaly as needed
                        continue;
                    }

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

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

                        //clear acked packet
                        pendingPacket.Packet.DontRecycleNow = false;
                        pendingPacket.Packet.Recycle();
                        pendingPacket.Clear();

                        // Packet found, remove it from the list
                        while (_tailPendingPacket.Packet == null && _tailPendingPacket != _headPendingPacket)
                        {
                            _tailPendingPacket = _tailPendingPacket.Next;
                        }

                        NetUtils.DebugWrite("[PA]Removing reliableInOrder ack: {0} - true", seqAck);
                        break;
                    }
                }
            }
            packet.Recycle();
            //Monitor.Exit(_pendingPackets);
        }
        public void SendNextPackets()
        {
            //check sending acks
            DateTime currentTime = DateTime.UtcNow;

            Monitor.Enter(_pendingPackets);
            //get packets from queue
            Monitor.Enter(_outgoingPackets);
            while (_outgoingPackets.Count > 0)
            {
                int relate = NetUtils.RelativeSequenceNumber(_localSeqence, _localWindowStart);
                if (relate < _windowSize)
                {
                    PendingPacket pendingPacket = _pendingPackets[_localSeqence % _windowSize];
                    pendingPacket.Packet          = _outgoingPackets.Dequeue();
                    pendingPacket.Packet.Sequence = (ushort)_localSeqence;
                    if (_headPendingPacket != null)
                    {
                        _headPendingPacket.Next = pendingPacket;
                        pendingPacket.Prev      = _headPendingPacket;
                    }
                    _headPendingPacket = pendingPacket;
                    _localSeqence      = (_localSeqence + 1) % NetConstants.MaxSequence;
                }
                else //Queue filled
                {
                    break;
                }
            }
            Monitor.Exit(_outgoingPackets);

            //if no pending packets return
            if (_headPendingPacket == null)
            {
                Monitor.Exit(_pendingPackets);
                return;
            }
            //send
            PendingPacket currentPacket = _headPendingPacket;

            do
            {
                if (currentPacket.TimeStamp.HasValue) //check send time
                {
                    double packetHoldTime = (currentTime - currentPacket.TimeStamp.Value).TotalMilliseconds;
                    if (packetHoldTime < _peer.ResendDelay)
                    {
                        continue;
                    }
                    NetUtils.DebugWrite("[RC]Resend: {0} > {1}", (int)packetHoldTime, _peer.ResendDelay);
                }

                currentPacket.TimeStamp = currentTime;
                _peer.SendRawData(currentPacket.Packet);
            } while ((currentPacket = currentPacket.Prev) != null);
            Monitor.Exit(_pendingPackets);
        }
 public bool TryGetNextIncomingPacket(out PendingPacket packet)
 {
     packet = null;
     if (incoming.Count == 0)
     {
         return(false);
     }
     return(incoming.TryDequeue(out packet));
 }
Exemple #18
0
 public override PendingPacket QueueIncomingPacket(EndPoint endPoint, Packet packet)
 {
     if (QueueOrDiscardPendingPackages(endPoint, PendingPacket.FromPacket(endPoint, packet)))
     {
         return(base.QueueIncomingPacket(endPoint, packet));
     }
     Console.WriteLine($"Dropping Packet from {endPoint}. Packet is too old {packet.Sequence} < {sequence}");
     return(null);
 }
Exemple #19
0
 protected virtual bool QueueOrDiscardPendingPackages(EndPoint endPoint, PendingPacket packet)
 {
     if (CheckSequence(packet.Sequence, remoteSequence))
     {
         remoteSequence = packet.Sequence;
         return(true);
     }
     return(false);
 }
 public bool HandleOutgoingPackage(ushort sequence, PendingPacket pendingPacket)
 {
     if (pendingPacket.PacketType != PacketType.Ack)
     {
         sent.Add(sequence, pendingPacket);
         return(true);
     }
     return(false);
 }
        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();
        }
Exemple #22
0
        public void ProcessPacketQueue()
        {
            lock (pendingPackets)
            {
                ProcessDelayedPackets();

                while (pendingPackets.Count > 0)
                {
                    PendingPacket packet = pendingPackets.Dequeue();
                    ReadPacket(new NetDataReader(packet.Data), packet.UserData);
                }
            }
        }
Exemple #23
0
        private ByteArray HandleNewPacket(ByteArray data)
        {
            log.Debug("Handling New Packet of size " + data.Length);
            byte b = data.ReadByte();

            if (~(b & 0x80) > 0)
            {
                throw new SFSError("Unexpected header byte: " + b + "\n" + DefaultObjectDumpFormatter.HexDump(data));
            }
            PacketHeader header = PacketHeader.FromBinary(b);

            pendingPacket = new PendingPacket(header);
            fsm.ApplyTransition(PacketReadTransition.HeaderReceived);
            return(ResizeByteArray(data, 1, data.Length - 1));
        }
 public void Clear()
 {
     if (Prev != null)
     {
         Prev.Next = Next;
     }
     if (Next != null)
     {
         Next.Prev = Prev;
     }
     Prev      = null;
     Next      = null;
     Packet    = null;
     TimeStamp = null;
 }
Exemple #25
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private ByteArray HandleNewPacket(ByteArray data)
        {
            log.Debug("Handling New Packet of size " + data.Length);
            byte headerByte = data.ReadByte();

            if (~(headerByte & 0x80) > 0)
            {
                throw new Exception(string.Concat("Unexpected header byte: ", headerByte));
            }
            PacketHeader header = PacketHeader.FromBinary(headerByte);

            pendingPacket = new PendingPacket(header);
            fsm.ApplyTransition(PacketReadTransition.HeaderReceived);
            return(ResizeByteArray(data, 1, data.Length - 1));
        }
 protected override bool QueueOrDiscardPendingPackages(EndPoint endPoint, PendingPacket packet)
 {
     foreach (var pending in pendingPackets)
     {
         if (pending.Key < RemoteSequence)
         {
             Incoming.Enqueue(pending.Value);
         }
     }
     if (!base.QueueOrDiscardPendingPackages(endPoint, packet))
     {
         pendingPackets.Add(packet.Sequence, packet);
         return(false);
     }
     return(true);
 }
Exemple #27
0
        public bool Tick()
        {
            PendingPacket firstPacket = null;

            while (pendingPackets.Count > 0 && firstPacket != pendingPackets.Peek())
            {
                var pendingPacket = pendingPackets.Dequeue();
                if (!OutPorts[pendingPacket.Port].ConnectedPortClosed && !OutPorts[pendingPacket.Port].TrySend(pendingPacket.Ip, true))
                {
                    if (firstPacket == null)
                    {
                        firstPacket = pendingPacket;
                    }
                    pendingPackets.Enqueue(pendingPacket);
                }
            }

            if ((!DoNotTerminateWhenInputPortsAreClosed && AllUpstreamPortsAreClosed()) || AllDownstreamPortsAreClosed())
            {
                Status = ProcessStatus.Terminated;
            }

            if (Status == ProcessStatus.Terminated)
            {
                return(false);
            }

            if (pendingPackets.Count > 0)
            {
                Status = ProcessStatus.Blocked;
                return(false);
            }
            else
            {
                var packetWasSentThisTick = false;
                if (HasInputPacketWaiting)
                {
                    Status = ProcessStatus.Active;
                    foreach (var kvp in InPorts)
                    {
                        packetWasSentThisTick = kvp.Value.Tick() || packetWasSentThisTick;
                    }
                }

                return(Update() || packetWasSentThisTick);
            }
        }
        public void ResendPackets()
        {
            long currentTime = NetTime.NowMs;

            //if no pending packets return
            if (_headPendingPacket == null)
            {
                //Monitor.Exit(_pendingPackets);
                SendAcks(false, currentTime);
                return;
            }

            //send
            long          resendDelay   = _peer.ResendDelay + _peer.NetManager.AvgUpdateTime;
            PendingPacket currentPacket = _headPendingPacket;
            int           countPack     = 0;

            do
            {
                countPack++;
                if (countPack > _windowSize)
                {
                    break;
                }
                if (currentPacket.SentCount > 0)                                 //check send time
                {
                    long packetHoldTime = currentTime - currentPacket.TimeStamp; // In Second
                    if (packetHoldTime < resendDelay * (1 + currentPacket.SentCount * currentPacket.SentCount))
                    {
                        continue;
                    }
                    NetUtils.DebugWrite("[RC]Resend: {0} > {1}", (int)packetHoldTime, resendDelay);
#if STATS_ENABLED || DEBUG
                    _peer.Statistics.PacketLoss++;
#endif
                }

                currentPacket.TimeStamp = currentTime;
                currentPacket.SentCount++;
                SendAcks(true, currentTime);
                _peer.SendRawData(currentPacket.Packet);
            }while ((currentPacket = currentPacket.Next) != null);
            //Monitor.Exit(_pendingPackets);

            SendAcks(false, currentTime);
        }
Exemple #29
0
            public NetPacket GetAndClear()
            {
                if (Prev != null)
                {
                    Prev.Next = Next;
                    Prev      = null;
                }
                if (Next != null)
                {
                    Next.Prev = Prev;
                    Next      = null;
                }

                var packet = Packet;

                Packet    = null;
                TimeStamp = null;
                return(packet);
            }
        public override PendingPacket QueueIncomingPacket(EndPoint endPoint, Packet packet)
        {
            PendingPacket pendingPacket = base.QueueIncomingPacket(endPoint, packet);

            foreach (var pending in pendingPackets)
            {
                if (!base.QueueOrDiscardPendingPackages(pending.Value.RemoteEndPoint, pending.Value))
                {
                    break;
                }
                Incoming.Enqueue(pending.Value);
            }
            long now = DateTime.Now.Ticks;

            for (int i = pendingPackets.Count - 1; i >= 0; i--)
            {
                if (pendingPackets.Keys[i] < RemoteSequence || (now - pendingPackets.Values[0].Sent > PacketExpire.Ticks))
                {
                    pendingPackets.RemoveAt(i);
                }
            }
            return(pendingPacket);
        }
Exemple #31
0
        private ByteArray HandleNewPacket(ByteArray data)
        {
            this.log.Debug(new string[]
            {
                "Handling New Packet of size " + data.Length
            });
            byte b = data.ReadByte();

            if (~(b & 128) > 0)
            {
                throw new AWError(string.Concat(new object[]
                {
                    "Unexpected header byte: ",
                    b,
                    "\n",
                    DefaultObjectDumpFormatter.HexDump(data)
                }));
            }
            PacketHeader header = PacketHeader.FromBinary((int)b);

            this.pendingPacket = new PendingPacket(header);
            this.fsm.ApplyTransition(PacketReadTransition.HeaderReceived);
            return(this.ResizeByteArray(data, 1, data.Length - 1));
        }