Esempio n. 1
0
        internal void OnSend(int packetId, long sequence, int payloadLength)
        {
            FlightSize += payloadLength + RUDPStack.RUDPHeaderLength + RUDPStack.UDPHeaderLength;

            //---- Update window (if needed)
            OnSend_UpdateWindow(payloadLength);

            //---- Sliding
            try
            {
                SWSlot slot;

                _sendSlotsLock.EnterWriteLock();

                //---- First slot
                if (_sendSlots.Count < 1)
                {
                    slot = new SWSlot(packetId, -1, sequence, sequence + payloadLength);
                    _sendSlots.Add(slot);
                    return;
                }

                //---- Check the last slot only, because ordered
                slot = _sendSlots[_sendSlots.Count - 1];

                // Grow the slot
                if ((slot.EndPacketId < 0 && slot.StartPacketId == packetId - 1) ||
                    (slot.EndPacketId > -1 && slot.EndPacketId == packetId - 1))
                {
                    slot.EndPacketId = packetId;
                    slot.EndByte    += payloadLength;
                    return;
                }

                // New slot
                slot = new SWSlot(packetId, -1, sequence, sequence + payloadLength);
                _sendSlots.Add(slot);
            }
            finally
            {
                _sendSlotsLock.ExitWriteLock();

                // Lock
                if (!CanSend(payloadLength))
                {
                    PauseTransmission();
                }
            }
        }
Esempio n. 2
0
		internal void OnACK(RUDPOutgoingPacket packet, double currentRTT)
		{
			// Duplicated ACK
			if (packet == null)
				return;

			FlightSize -= packet.Payload.Length + RUDPStack.UDPHeaderLength;

			//---- Congestion
			lock (this)
			{
				OnACK_UpdateParameters(packet, currentRTT);
				OnACK_UpdateWindow(packet);
			}

			//---- Sliding
			int packetId = packet.PacketId;

			_sendSlotsLock.EnterWriteLock();

			SWSlot slot = null;
			try
			{
				for (int index = 0; index < _sendSlots.Count; index++)
				{
					slot = _sendSlots[index];

					// Delete this slot
					if (slot.EndPacketId < 0 && slot.StartPacketId == packetId)
					{
						_sendSlots.RemoveAt(index);
						return;
					}

					// Decrease the slot
					if (slot.EndPacketId > -1 && slot.StartPacketId == packetId)
					{
						slot.StartPacketId++;
						slot.StartByte += packet.Payload.Length;
						if (slot.StartPacketId == slot.EndPacketId)
							slot.EndPacketId = -1;
						return;
					}

					// Decrease the slot
					if (slot.EndPacketId > -1 && slot.EndPacketId == packetId)
					{
						slot.EndPacketId--;
						slot.EndByte -= packet.Payload.Length;
						if (slot.StartPacketId == slot.EndPacketId)
							slot.EndPacketId = -1;
						return;
					}

					// Split the slot
					if (slot.EndPacketId > -1 && slot.StartPacketId <= packetId && slot.EndPacketId >= packetId)
					{
						// Right slot
						SWSlot newSlot = new SWSlot(packetId + 1,
													slot.EndPacketId,
													packet.Sequence + packet.Payload.Length + 1,
													slot.EndByte);
						if (newSlot.StartPacketId == newSlot.EndPacketId)
							newSlot.EndPacketId = -1;
						_sendSlots.Insert(index + 1, newSlot);

						// Left slot
						slot.EndPacketId = packetId - 1;
						slot.EndByte = packet.Sequence - 1;
						if (slot.StartPacketId == slot.EndPacketId)
							slot.EndPacketId = -1;

						return;
					}
				}

			}
			finally
			{
				_sendSlotsLock.ExitWriteLock();
				ResumeTransmission();
			}
		}
Esempio n. 3
0
		internal void OnSend(int packetId, long sequence, int payloadLength)
		{
			FlightSize += payloadLength + RUDPStack.RUDPHeaderLength + RUDPStack.UDPHeaderLength;

			//---- Update window (if needed)
			OnSend_UpdateWindow(payloadLength);

			//---- Sliding
			try
			{
				SWSlot slot;

				_sendSlotsLock.EnterWriteLock();

				//---- First slot
				if (_sendSlots.Count < 1)
				{
					slot = new SWSlot(packetId, -1, sequence, sequence + payloadLength);
					_sendSlots.Add(slot);
					return;
				}

				//---- Check the last slot only, because ordered
				slot = _sendSlots[_sendSlots.Count - 1];

				// Grow the slot
				if ((slot.EndPacketId < 0 && slot.StartPacketId == packetId - 1) ||
					(slot.EndPacketId > -1 && slot.EndPacketId == packetId - 1))
				{
					slot.EndPacketId = packetId;
					slot.EndByte += payloadLength;
					return;
				}

				// New slot
				slot = new SWSlot(packetId, -1, sequence, sequence + payloadLength);
				_sendSlots.Add(slot);
			}
			finally
			{
				_sendSlotsLock.ExitWriteLock();

				// Lock
				if (!CanSend(payloadLength))
					PauseTransmission();
			}
		}
Esempio n. 4
0
        internal void OnACK(RUDPOutgoingPacket packet, double currentRTT)
        {
            // Duplicated ACK
            if (packet == null)
            {
                return;
            }

            FlightSize -= packet.Payload.Length + RUDPStack.UDPHeaderLength;

            //---- Congestion
            lock (this)
            {
                OnACK_UpdateParameters(packet, currentRTT);
                OnACK_UpdateWindow(packet);
            }

            //---- Sliding
            int packetId = packet.PacketId;

            _sendSlotsLock.EnterWriteLock();

            SWSlot slot = null;

            try
            {
                for (int index = 0; index < _sendSlots.Count; index++)
                {
                    slot = _sendSlots[index];

                    // Delete this slot
                    if (slot.EndPacketId < 0 && slot.StartPacketId == packetId)
                    {
                        _sendSlots.RemoveAt(index);
                        return;
                    }

                    // Decrease the slot
                    if (slot.EndPacketId > -1 && slot.StartPacketId == packetId)
                    {
                        slot.StartPacketId++;
                        slot.StartByte += packet.Payload.Length;
                        if (slot.StartPacketId == slot.EndPacketId)
                        {
                            slot.EndPacketId = -1;
                        }
                        return;
                    }

                    // Decrease the slot
                    if (slot.EndPacketId > -1 && slot.EndPacketId == packetId)
                    {
                        slot.EndPacketId--;
                        slot.EndByte -= packet.Payload.Length;
                        if (slot.StartPacketId == slot.EndPacketId)
                        {
                            slot.EndPacketId = -1;
                        }
                        return;
                    }

                    // Split the slot
                    if (slot.EndPacketId > -1 && slot.StartPacketId <= packetId && slot.EndPacketId >= packetId)
                    {
                        // Right slot
                        SWSlot newSlot = new SWSlot(packetId + 1,
                                                    slot.EndPacketId,
                                                    packet.Sequence + packet.Payload.Length + 1,
                                                    slot.EndByte);
                        if (newSlot.StartPacketId == newSlot.EndPacketId)
                        {
                            newSlot.EndPacketId = -1;
                        }
                        _sendSlots.Insert(index + 1, newSlot);

                        // Left slot
                        slot.EndPacketId = packetId - 1;
                        slot.EndByte     = packet.Sequence - 1;
                        if (slot.StartPacketId == slot.EndPacketId)
                        {
                            slot.EndPacketId = -1;
                        }

                        return;
                    }
                }
            }
            finally
            {
                _sendSlotsLock.ExitWriteLock();
                ResumeTransmission();
            }
        }