Example #1
0
        /// <summary>
        /// Updates the state of the peer and sends packets if needed.
        /// </summary>
        internal void _Update(UDPHub Hub, double Time, out bool Remove)
        {
            UDPHubSettings settings = this._Settings;
            OutTerminal oterm = this._OutTerminal;

            // Handle waves
            this._WaveDelay -= Time;
            if (this._WaveDelay <= 0.0)
            {
                // Check acknowledgement and adjust wave size
                if (oterm.AcknowledgementNumber == oterm.SendNumber)
                {
                    if (this._FullWave)
                    {
                        this._WaveSize++;
                        this._FullWave = false;
                    }
                }
                else
                {
                    oterm.SendNumber = oterm.AcknowledgementNumber;
                    if (this._WaveSize > 1)
                    {
                        this._WaveSize--;
                    }
                }

                int chunksequencenumber = 0;
                byte[] chunkdata = null;
                bool chunkinitial = false;
                bool chunkfinal = false;
                int wavesize = 0;
                if (oterm.Process(ref chunksequencenumber, ref chunkdata, ref chunkinitial, ref chunkfinal))
                {
                    while (true)
                    {
                        // Send chunk
                        wavesize++;
                        Packet chunk = new Packet
                        {
                            SequenceNumber = chunksequencenumber,
                            ChunkData = chunkdata,
                            ChunkInitial = chunkinitial,
                            ChunkFinal = chunkfinal
                        };
                        this._FillAdditional(chunk);
                        Hub.Send(chunk, this._EndPoint);

                        // Check if wave is full
                        if (wavesize == this._WaveSize)
                        {
                            this._FullWave = true;
                            break;
                        }

                        // Get next chunk
                        if (!oterm.Process(ref chunksequencenumber, ref chunkdata, ref chunkinitial, ref chunkfinal))
                        {
                            break;
                        }
                    }

                    // Reset delays
                    this._WaveDelay = this._RoundTripTime + settings.WaveRate;
                    this._KeepAliveDelay = settings.KeepAliveDelay;
                }
            }

            // Send keep alive if needed
            this._KeepAliveDelay -= Time;
            if (this._KeepAliveDelay <= 0.0)
            {
                Packet packet = new Packet
                {
                    SequenceNumber = this._OutTerminal.SendNumber
                };
                this._FillAdditional(packet);
                Hub.Send(packet, this.EndPoint);
                this._KeepAliveDelay = settings.KeepAliveDelay;
            }

            // Check for implicit disconnect
            Remove = false;
            this._ExpireDelay -= Time;
            if (this._ExpireDelay <= 0.0)
            {
                Remove = true;
            }
        }
Example #2
0
 /// <summary>
 /// Immediately sends a ping response packet of some sort.
 /// </summary>
 private void _SendPingResponse(UDPHub Hub)
 {
     byte[] data = null;
     bool initial = false;
     bool final = false;
     int sequencenumber = 0;
     Packet packet;
     if(this._OutTerminal.Process(ref sequencenumber, ref data, ref initial, ref final))
     {
         packet = new Packet
         {
             SequenceNumber = sequencenumber,
             ChunkData = data,
             ChunkInitial = initial,
             ChunkFinal = final
         };
     }
     else
     {
         packet = new Packet
         {
             SequenceNumber = this._OutTerminal.SendNumber
         };
     }
     packet.PingResponse = true;
     Hub.Send(packet, this.EndPoint);
 }
Example #3
0
        /// <summary>
        /// Called when an (unvalidated) packet is received for this peer.
        /// </summary>
        internal void _Receive(UDPHubSettings Settings, UDPHub Hub, Packet Packet, out bool Remove)
        {
            Remove = false;

            // Validate
            if (!this._Valid(Packet.SequenceNumber))
                return;

            // Disconnect?
            if (Packet.Disconnect)
            {
                Remove = true;
                return;
            }

            // Reset expire delay
            this._ExpireDelay = Settings.ExpireDelay;

            // Read additional information
            int ack;
            if (Packet.AcknowledgementNumber.TryGetValue(out ack))
            {
                this._OutTerminal.AcknowledgementNumber = ack;
            }
            double rtt;
            if (Packet.RoundTripTime.TryGetValue(out rtt))
            {
                this._RoundTripTime = rtt;
            }

            // Chunk?
            if (Packet.ChunkData != null)
            {
                this._Process(Packet.SequenceNumber, Packet.ChunkData, Packet.ChunkInitial, Packet.ChunkFinal);
            }

            // Ping?
            if (Packet.PingRequest)
            {
                this._SendPingResponse(Hub);
            }
        }