示例#1
0
		internal static void ReleaseFragmentInformation(FragmentInformation fragment)
		{
			//return;
			_fragmentsPools.Enqueue(fragment);
		}
示例#2
0
		/// <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;
		}