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(); } } }
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(); } }
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(); } }
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(); } }