⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractwindow.cs

📁 破解的飞信源代码
💻 CS
字号:
namespace NCindy.Protocol.RUDP.Window
{
    using NCindy.Protocol.RUDP;
    using NCindy.Protocol.RUDP.MTUTuning;
    using NCindy.Protocol.RUDP.Packet;
    using NCindy.Protocol.RUDP.Stack;
    using NCindy.Threading;
    using System;
    using System.Collections.Generic;
    using System.Threading;

    internal abstract class AbstractWindow
    {
        internal int _awnd = 0x7fffffff;
        internal double _cwnd;
        internal ManualResetEvent _event = new ManualResetEvent(true);
        internal RUDPSocket _rudp;
        internal int _rwnd;
        private List<SWSlot> _sendSlots = new List<SWSlot>();
        private ReaderWriterLockSlim _sendSlotsLock = new ReaderWriterLockSlim();
        internal bool _transmissionPaused;
        internal int FlightSize;

        internal AbstractWindow(RUDPSocket rudp)
        {
            this._rudp = rudp;
        }

        internal bool CanReceive(int packetId, int length)
        {
            int biggestPacketId = this._rudp._incomingPackets.BiggestPacketId;
            return ((packetId < biggestPacketId) || (this._rudp._receiveSize > (this._rwnd + length)));
        }

        internal bool CanSend(int payloadLength)
        {
            if (this._transmissionPaused)
            {
                return true;
            }
            this._sendSlotsLock.EnterReadLock();
            if (this._sendSlots.get_Count() < 1)
            {
                this._sendSlotsLock.ExitReadLock();
                return true;
            }
            long startByte = this._sendSlots.get_Item(0).StartByte;
            long endByte = this._sendSlots.get_Item(this._sendSlots.get_Count() - 1).EndByte;
            this._sendSlotsLock.ExitReadLock();
            return (Math.Min((double) Math.Max(this._awnd, this._rudp._mtu), Math.Min((double) this._rudp._sendSize, this.CWND)) >= ((payloadLength + endByte) - startByte));
        }

        internal void OnACK(RUDPOutgoingPacket packet, double currentRTT)
        {
            if (packet != null)
            {
                this.FlightSize -= packet.Payload.Length + 0x1c;
                lock (this)
                {
                    this.OnACK_UpdateParameters(packet, currentRTT);
                    this.OnACK_UpdateWindow(packet);
                }
                int packetId = packet.PacketId;
                this._sendSlotsLock.EnterWriteLock();
                SWSlot slot = null;
                try
                {
                    for (int i = 0; i < this._sendSlots.get_Count(); i++)
                    {
                        slot = this._sendSlots.get_Item(i);
                        if ((slot.EndPacketId < 0) && (slot.StartPacketId == packetId))
                        {
                            this._sendSlots.RemoveAt(i);
                            return;
                        }
                        if ((slot.EndPacketId > -1) && (slot.StartPacketId == packetId))
                        {
                            slot.StartPacketId++;
                            slot.StartByte += packet.Payload.Length;
                            if (slot.StartPacketId == slot.EndPacketId)
                            {
                                slot.EndPacketId = -1;
                            }
                            return;
                        }
                        if ((slot.EndPacketId > -1) && (slot.EndPacketId == packetId))
                        {
                            slot.EndPacketId--;
                            slot.EndByte -= packet.Payload.Length;
                            if (slot.StartPacketId == slot.EndPacketId)
                            {
                                slot.EndPacketId = -1;
                            }
                            return;
                        }
                        if (((slot.EndPacketId > -1) && (slot.StartPacketId <= packetId)) && (slot.EndPacketId >= packetId))
                        {
                            SWSlot slot2 = new SWSlot(packetId + 1, slot.EndPacketId, (packet.Sequence + packet.Payload.Length) + 1, slot.EndByte);
                            if (slot2.StartPacketId == slot2.EndPacketId)
                            {
                                slot2.EndPacketId = -1;
                            }
                            this._sendSlots.Insert(i + 1, slot2);
                            slot.EndPacketId = packetId - 1;
                            slot.EndByte = packet.Sequence - 1;
                            if (slot.StartPacketId == slot.EndPacketId)
                            {
                                slot.EndPacketId = -1;
                            }
                            return;
                        }
                    }
                }
                finally
                {
                    this._sendSlotsLock.ExitWriteLock();
                    this.ResumeTransmission();
                }
            }
        }

        internal void OnACK_UpdateParameters(RUDPOutgoingPacket packet, double currentRTT)
        {
            double rtt = this._rudp.RTT;
            double deltaRTT = this._rudp.DeltaRTT;
            if (packet.Retransmission < 1)
            {
                if (this._rudp._rtt == 0)
                {
                    rtt = currentRTT;
                    deltaRTT = currentRTT / 2;
                }
                else
                {
                    rtt = (0.875 * rtt) + (0.125 * currentRTT);
                    double num3 = currentRTT - rtt;
                    deltaRTT = (0.75 * deltaRTT) + (0.25 * Math.Abs(num3));
                }
            }
            double rto = rtt + Math.Max((double) 4, (double) (4 * deltaRTT));
            if (rto > 60000000)
            {
                rto = 60000000;
            }
            long sto = (long) (15000000 + (4 * rtt));
            this._rudp.SetRTT(rtt, deltaRTT, rto, sto);
        }

        internal abstract void OnACK_UpdateWindow(RUDPOutgoingPacket packet);
        internal virtual void OnEndFastRetransmit()
        {
        }

        internal virtual void OnOutOfOrder(int startPacketId, int endPacketId)
        {
        }

        internal void OnReceive(RUDPIngoingPacket packet)
        {
            if (packet != null)
            {
                Interlocked.Exchange(ref this._rwnd, this._rwnd + packet.Payload.Length);
            }
        }

        internal void OnReceiveAdvertisedWindow(int windowSize)
        {
            this._awnd = windowSize;
        }

        internal void OnReceiveProcessed(RUDPIngoingPacket packet)
        {
            Interlocked.Exchange(ref this._rwnd, this._rwnd - packet.Payload.Length);
        }

        internal void OnSend(int packetId, long sequence, int payloadLength)
        {
            this.FlightSize += (payloadLength + 0x3f) + 0x1c;
            this.OnSend_UpdateWindow(payloadLength);
            try
            {
                SWSlot slot;
                this._sendSlotsLock.EnterWriteLock();
                if (this._sendSlots.get_Count() < 1)
                {
                    slot = new SWSlot(packetId, -1, sequence, sequence + payloadLength);
                    this._sendSlots.Add(slot);
                }
                else
                {
                    slot = this._sendSlots.get_Item(this._sendSlots.get_Count() - 1);
                    if (((slot.EndPacketId < 0) && (slot.StartPacketId == (packetId - 1))) || ((slot.EndPacketId > -1) && (slot.EndPacketId == (packetId - 1))))
                    {
                        slot.EndPacketId = packetId;
                        slot.EndByte += payloadLength;
                    }
                    else
                    {
                        slot = new SWSlot(packetId, -1, sequence, sequence + payloadLength);
                        this._sendSlots.Add(slot);
                    }
                }
            }
            finally
            {
                this._sendSlotsLock.ExitWriteLock();
                if (!this.CanSend(payloadLength))
                {
                    this.PauseTransmission();
                }
            }
        }

        internal virtual void OnSend_UpdateWindow(int payloadLength)
        {
        }

        internal void OnTimeOut(RUDPOutgoingPacket packet)
        {
            lock (this)
            {
                this.OnTimeOut_UpdateParameters(packet);
                this.OnTimeOut_UpdateWindow();
            }
        }

        internal void OnTimeOut_UpdateParameters(RUDPOutgoingPacket packet)
        {
            if (packet.Retransmission > 0)
            {
                this._rudp.RTO = Math.Min((int) (this._rudp.RTO * 2), 0x3938700);
                this._rudp.STO = (int) (15000000 + (4 * this._rudp.RTT));
            }
        }

        internal abstract void OnTimeOut_UpdateWindow();
        internal void PauseTransmission()
        {
            this._transmissionPaused = true;
            this._event.Reset();
            RUDPStack.ForceFragmentsSending(this._rudp._controlThreadId);
        }

        internal virtual void Reset()
        {
            this._sendSlotsLock.EnterWriteLock();
            this._sendSlots.Clear();
            this._sendSlotsLock.ExitWriteLock();
            this._cwnd = 2 * PMTUDiscovery.MinMTU;
            this._awnd = 0x7fffffff;
            this._rwnd = 0;
            this._rudp.SetRTT(0, 0, 3000000, (long) (15000000 + (4 * this._rudp._rto)));
            if (this._event != null)
            {
                this._event.Set();
                RUDPStack.ForceFragmentsSending(this._rudp._controlThreadId);
            }
        }

        internal void ResumeTransmission()
        {
            this._transmissionPaused = false;
            if (this.CanSend(0))
            {
                this._event.Set();
                RUDPStack.ForceFragmentsSending(this._rudp._controlThreadId);
            }
        }

        internal void WaitOne()
        {
            this._event.WaitOne(1, true);
        }

        internal int AdvertisedWindow
        {
            get
            {
                return (this._rudp._receiveSize - this._rwnd);
            }
        }

        internal double CWND
        {
            get
            {
                return Thread.VolatileRead(ref this._cwnd);
            }
            set
            {
                Thread.VolatileWrite(ref this._cwnd, Math.Max((double) this._rudp._mtu, value));
            }
        }

        internal ManualResetEvent WaitObject
        {
            get
            {
                return this._event;
            }
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -