// NOTE: This makes the channel unusuable. internal void ReturnLeasedDatagrams() { var queue = GetQueue(); while (queue.Count > 0) { datagramPool.Return(queue.Dequeue()); } datagramPool.Return(currentDatagram); }
private bool TrySendDatagram(Datagram datagram, bool hasAlreadyBeenDelayed = false) { // If we are the keep alive master (i.e. this remote peer is not) and this // packet is reliable: update ellpasedMilliseondsAtLastRealiablePacket[Sent] if (!IsKeepAliveMaster && datagram.IsReliable) { ellapasedSecondsSinceLastRealiablePacket = 0.0f; } // simulate packet loss if (localPeer.SimulatePacketLossProbability > 0.0) { if (SingleRandom.NextDouble() < localPeer.SimulatePacketLossProbability) { localPeer.Log(LogLevel.Info, String.Format("DROPPED packet to send - simulate packet loss set at: {0}", localPeer.SimulatePacketLossChance)); return(true); } } // if reliable and not already delayed update time sent used to measure RTT when ACK response received if (datagram.IsReliable && !hasAlreadyBeenDelayed) { datagram.EllapsedAtSent = localPeer.Stopwatch.Elapsed; } // simulate delay if (localPeer.SimulateLatencySeconds > 0.0f && !hasAlreadyBeenDelayed && datagram.Type != PacketType.Bye) // if Bye we don't delay as if closing will not be sent { float delay = localPeer.SimulateLatencySeconds; // jitter if (localPeer.SimulateJitterSeconds > 0.0f) { float jitter = localPeer.SimulateJitterSeconds * (float)SingleRandom.NextDouble(); if (SingleRandom.NextDouble() < 0.5) { jitter *= -1; } delay += jitter; } DelayedDatagram delayedDatagram = new DelayedDatagram(delay, datagram); localPeer.Log(LogLevel.Debug, String.Format("...DELAYED Sending datagram to: {0}, seq {1}, channel: {2}, total size: {3}; by {4}s...", endPoint.ToString(), datagram.Sequence.ToString(), datagram.SendOptions.ToString(), datagram.Count.ToString(), delayedDatagram.EllapsedSecondsRemainingToDelay.ToString())); delayedDatagrams.Add(delayedDatagram); return(true); } localPeer.Log(LogLevel.Debug, String.Format("--> Sending datagram to: {0}, seq {1}, channel: {2}, total size: {3}...", endPoint.ToString(), datagram.Sequence.ToString(), datagram.SendOptions.ToString(), datagram.Count.ToString())); // Expedite send if less than 5% of recent reliable packets have to be re-sent bool expedite = qualityOfService.ResendRatio < 0.05f; //----------------------------------------------------------------------------------------------------------------- bool success = localPeer.Transceiver.Send(datagram.BackingBuffer, datagram.Offset, datagram.Count, endPoint, expedite); //----------------------------------------------------------------------------------------------------------------- if (success) { if (localPeer.IsCollectingStatistics) { localPeer.Statistics.AddBytesSent(datagram.Count); } // return the datagram to pool for re-use if we are not waiting for an ACK if (!datagram.IsReliable) { sendDatagramsPool.Return(datagram); } } else { // something fatal has gone wrong and this peer can no longer be sent to localPeer.RemovePeerOnNextUpdate(this); } return(success); }