internal static void ReleaseFragmentInformation(FragmentInformation fragment) { //return; _fragmentsPools.Enqueue(fragment); }
/// <summary> /// Send all the fragments. /// </summary> /// <returns>True if all the fragments have been sent</returns> static private bool SendFragments(FragmentInformation fragments, ControlThreadInformation controlInformation) { controlInformation._chargeCheckStopWatch.Reset(); controlInformation._chargeCheckStopWatch.Start(); while (fragments.Size > 0) { //---- MSS : Full header (IP + UDP + RUDP) int MSS = fragments.rudp._mtu - (RUDPStack.UDPHeaderLength + RUDPStack.RUDPHeaderLength); int currentLength = Math.Min(MSS, fragments.Size); //---- If reliable, wait for the congestion windows if (fragments.IsReliable && !fragments.rudp._controlWindow.CanSend(currentLength)) return false; //---- Send if (!PushPacketToSend(fragments.rudp, fragments.IsReliable, RUDPPacketChannel.UserPacket, fragments.Payload, fragments.Offset, currentLength)) { fragments.Error = RUDPSocketError.SocketError; if (fragments.AsyncResult != null) OnSocketUnhandledError(fragments.rudp, fragments.Error, fragments.AsyncResult); return true; } fragments.Size -= currentLength; fragments.Offset += currentLength; //--- Avoid to block the Control thread, because sending a lot of fragments (allow to send ACKs too...) if (fragments.Size > 0 && controlInformation._chargeCheckStopWatch.ElapsedMilliseconds > 0) return false; } //---- End of send if (fragments.AsyncResult != null) fragments.rudp._physical.OnEndSend(fragments.rudp, fragments.AsyncResult); return true; }