⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udtsocket.cs

📁 rudp可靠保障得udp传输
💻 CS
📖 第 1 页 / 共 2 页
字号:
				}
			}

			catch (Exception e)
			{
				Console.WriteLine(e.Message);
				return 0;
			}
#endif
		}

		#endregion

		#region REMOVED: GetOverlappedResult
		/*
		public void GetOverlappedResult(int overlappedIOHandle, ref int progress, bool wait)
		{
			API_Getoverlappedresult(_handle, overlappedIOHandle, ref progress, wait);
		}
		*/
		#endregion

		#region UDT Thread - ASync Management

		// List of sockets waiting for accept
		static List<AsyncAcceptRegistration> _acceptRegistrations = new List<AsyncAcceptRegistration>(100);

		// List of sockets waiting for receive
		static List<AsyncReceiveRegistration> _receiveRegistrations = new List<AsyncReceiveRegistration>(100);

		static private void UDTThreadProcessing()
		{

			try
			{
				while (Thread.CurrentThread.IsAlive)
				{
					//---- Accept

					for (int index = _acceptRegistrations.Count - 1; index > -1; index--)
					{
						Monitor.Enter(_acceptRegistrations);
						AsyncAcceptRegistration registration = _acceptRegistrations[index];
						Monitor.Exit(_acceptRegistrations);

						if (registration.Socket.IsOnAccept)
						{
							// Stop "BeginAccept"
							lock (_acceptRegistrations)
								_acceptRegistrations.RemoveAt(index);

							// Queue it for the call back
							_processor.AddCommand(registration);
						}
					}

					//---- Receive

					for (int index = _receiveRegistrations.Count - 1; index > -1; index--)
					{
						Monitor.Enter(_receiveRegistrations);
						AsyncReceiveRegistration registration = _receiveRegistrations[index];
						Monitor.Exit(_receiveRegistrations);

						if (!registration.Socket.Connected || registration.Socket.IsOnRead)
						{
							// Stop "BeginReceive"
							lock (_receiveRegistrations)
								_receiveRegistrations.RemoveAt(index);

							// Queue it for the call back
							_processor.AddCommand(registration);
						}
					}

					//---- Like "Select" Wait for an event or 1 millisecond
					API_WaitForEvent();
				}
			}
			catch (ThreadInterruptedException)
			{ }
		}

		#endregion

		#region BeginAccept

		public IAsyncResult BeginAccept(AsyncCallback callback, object state)
		{
			AsyncAcceptRegistration asyncRegistration = new AsyncAcceptRegistration(this, callback, state);
			lock (_acceptRegistrations)
				_acceptRegistrations.Add(asyncRegistration);

			return null;
		}

		public UDTSocket EndAccept(IAsyncResult ar)
		{
			return (UDTSocket)((UDTAsyncResult)ar)._socket;
		}

		#endregion

		#region BeginConnect

		public IAsyncResult BeginConnect(IPEndPoint endPoint, AsyncCallback callback, object state)
		{
			AsyncConnectRegistration asyncRegistration = new AsyncConnectRegistration(this, endPoint, callback, state);

			_processor.AddCommand(asyncRegistration);

			return null;
		}

		public void EndConnect(IAsyncResult ar)
		{

			if (((UDTAsyncResult)ar).Exception != null)
			{
				throw ((UDTAsyncResult)ar).Exception;
			}
		}

		#endregion

		#region BeginReceive

		public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback, object state)
		{
			AsyncReceiveRegistration asyncRegistration = new AsyncReceiveRegistration(this, buffer, offset, size, socketFlags, callback, state);
			lock (_receiveRegistrations)
				_receiveRegistrations.Add(asyncRegistration);

			return null;
		}

		public int EndReceive(IAsyncResult ar)
		{
			return ((UDTAsyncResult)ar)._size;
		}

		#endregion

		#region BeginSend

		public IAsyncResult BeginSend(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError error, AsyncCallback callback, object state)
		{
			error = SocketError.Success;

			try
			{
				return BeginSend(buffer, offset, size, socketFlags, callback, state);
			}
			catch (Exception)
			{
				error = SocketError.SocketError;
				return null;
			}
		}

		public IAsyncResult BeginSend(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback, object state)
		{
			AsyncSendRegistration asyncRegistration = new AsyncSendRegistration(this, buffer, offset, size, socketFlags, callback, state);

			IntPtr pointer = GCHandle.ToIntPtr(GCHandle.Alloc(asyncRegistration));

			if (UDT_ERROR == API_BeginSend(_handle, buffer, size, (int)socketFlags, pointer))
				throw new UDTSocketException();

			// HACK !!!!!
			_processor.AddCommand(asyncRegistration);

			return null;
		}

		private static void UDTEndSendCallback(IntPtr pointer)
		{
			AsyncSendRegistration asyncRegistration = (AsyncSendRegistration)GCHandle.FromIntPtr(pointer).Target;
			_processor.AddCommand(asyncRegistration);
		}

		public int EndSend(IAsyncResult ar)
		{
			return ((UDTAsyncResult)ar)._size;
		}

		#endregion

		#region IsOn...

		public bool IsOnAccept
		{
			get
			{
#if UDT_FULLTCP
                List<System.Net.Sockets.Socket> list = new List<System.Net.Sockets.Socket>(1);
                list.Add(_tcpSocket);

                System.Net.Sockets.Socket.Select(list, null, null, 0);

                if (list.Count < 1)
                    return false;

                return true;
#else
				return API_IsOnAccept(_handle);
#endif
			}
		}

		public bool IsOnRead
		{
			get
			{
#if UDT_FULLTCP
                List<System.Net.Sockets.Socket> list = new List<System.Net.Sockets.Socket>(1);
                list.Add(_tcpSocket);

                System.Net.Sockets.Socket.Select(list, null, null, 0);

                if (list.Count < 1)
                    return false;

                return true;
#else
				return API_IsOnRead(_handle);
#endif
			}
		}

		public bool IsOnWrite
		{
			get
			{
#if UDT_FULLTCP
                return true;
#else
				return API_IsOnWrite(_handle);
#endif
			}
		}

		public bool IsOnError
		{
			get
			{
#if UDT_FULLTCP
                return false;
#else
				return API_IsOnError(_handle);
#endif
			}
		}

		#endregion

		#region SetSocketOption

		public void SetSocketOption(SocketOptionLevel optionLevel, UDTSocketOptionName optionName, int optionValue)
		{
			SetSocketOption(optionLevel, optionName, (object)optionValue);
		}

		public void SetSocketOption(SocketOptionLevel optionLevel, UDTSocketOptionName optionName, object optionValue)
		{
#if UDT_FULLTCP
            //_tcpSocket.SetSocketOption(optionLevel, optionName, optionValue);
#else
			//---- UDT
			int size = -1;

			if (optionValue is int)
				size = sizeof(int);

			else if (optionValue is long)
				size = sizeof(long);

			else if (optionValue is LingerOption)
			{
				// If false it is the default behaviors.
				// If true the socket "close" method will wait that all the sending data have been send and
				// that he has receive the ack. The close method does not return until all the data is delivered
				// or until "time" (second linger option) has expired).
				/*
				UDTLinger linger = new UDTLinger();
				linger.OnOff = ((LingerOption)optionValue).Enabled ? ((short)1) : ((short)0);
				linger.Time = (short)((LingerOption)optionValue).LingerTime;

				size = Marshal.SizeOf(typeof(UDTLinger));

				optionValue = linger;*/
				return;
			}

			else throw new NotImplementedException();

			try
			{
				API_Setsockopt(_handle, (int)optionLevel, optionName, ref optionValue, size);
			}

			catch (Exception e)
			{
				Console.Write(e.Message);
			}

			//API_Setsockopt(int handle, int level, UDTOption option, ref int optionValue /*const void* optval*/, int optlen);
#endif
		}

		#endregion

		#region Properties

		public bool Connected
		{
			get
			{
#if UDT_FULLTCP
            return _tcpSocket.Connected;
#else

				if (_handle < 0)
					return false;

				return API_IsConnected(_handle);
#endif
			}
		}

		public EndPoint LocalEndPoint
		{
			get
			{
#if UDT_FULLTCP
                return _tcpSocket.LocalEndPoint;
#else
				return _localEndPoint;
#endif
			}
		}

		public EndPoint RemoteEndPoint
		{
			get
			{
#if UDT_FULLTCP
                return _tcpSocket.RemoteEndPoint;
#else
				return _remoteEndPoint;
#endif
			}
		}

		public int Handle
		{
			get
			{
#if UDT_FULLTCP
            return _tcpSocket.Handle.ToInt32();
#else
				return _handle;
#endif
			}
		}

		private bool IsAsynchronous
		{
			get
			{
				throw new NotImplementedException();
			}
			set
			{
				//API_SetAsynchronous(_handle, value);
			}
		}

		#endregion

		#region Options

		public int SendTimeOut
		{
			get
			{
				throw new NotImplementedException();
			}
			set
			{
				SetSocketOption(SocketOptionLevel.IP, UDTSocketOptionName.UDT_SNDTIMEO, value);
				//API_Setsockopt(this._handle, 0, (int)UDTOption.UDT_SNDTIMEO, ref (object)value, 4);
			}
		}

		public int ReceiveTimeOut
		{
			get
			{
				throw new NotImplementedException();
			}
			set
			{
				SetSocketOption(SocketOptionLevel.IP, UDTSocketOptionName.UDT_RCVTIMEO, value);
				//API_Setsockopt(this._handle, 0, (int)UDTOption.UDT_RCVTIMEO, ref (object)value, 4);
			}
		}

		#endregion

		#region DEBUG...

		[System.Diagnostics.Conditional("UDT_TRACE")]
		static private void UDTTrace(string message)
		{
			Console.WriteLine(message);
		}

		#endregion

	}

	#region UDTSocketOptionName

	public enum UDTSocketOptionName
	{
		UDT_MSS = 0, // the Maximum Transfer Unit
		UDT_SNDSYN = 1, // if sending is blocking
		UDT_RCVSYN = 2, // if receiving is blocking
		UDT_CC = 3, // custom congestion control algorithm
		UDT_FC = 4, // deprecated, for compatibility only
		UDT_SNDBUF = 5, // maximum buffer in sending queue
		UDT_RCVBUF = 6, // UDT receiving buffer size
		UDT_LINGER = 7, // waiting for unsent data when closing
		UDP_SNDBUF = 8, // UDP sending buffer size
		UDP_RCVBUF = 9, // UDP receiving buffer size
		UDT_MAXMSG = 10, // maximum datagram message size
		UDT_MSGTTL = 11, // time-to-live of a datagram message
		UDT_RENDEZVOUS = 12, // rendezvous connection mode
		UDT_SNDTIMEO = 13, // send() timeout
		UDT_RCVTIMEO = 14 // recv() timeout
	}

	#endregion

	#region UDTAsyncResult

	public sealed class UDTAsyncResult : IAsyncResult
	{

		internal object _stateObject;
		internal int _size;
		internal UDTSocket _socket;
		internal int _overlappedIoHanlde;
		internal UDTSocketException Exception;

		public UDTAsyncResult(int size, object stateObject, UDTSocket socket, int overlappedIoHanlde)
		{
			_size = size;
			_stateObject = stateObject;
			_socket = socket;
			_overlappedIoHanlde = overlappedIoHanlde;
		}

		public UDTAsyncResult(int size, object stateObject)
		{
			_size = size;
			_stateObject = stateObject;
		}

		// Summary:
		//     Gets a System.Threading.WaitHandle that is used to wait for an asynchronous
		//     operation to complete.
		//
		// Returns:
		//     A System.Threading.WaitHandle that is used to wait for an asynchronous operation
		//     to complete.
		public WaitHandle AsyncWaitHandle
		{
			get { return null; }
		}

		// Summary:
		//     Gets an indication of whether the asynchronous operation completed synchronously.
		//
		// Returns:
		//     true if the asynchronous operation completed synchronously; otherwise, false.
		public bool CompletedSynchronously
		{
			get { return true; }
		}

		// Summary:
		//     Gets an indication whether the asynchronous operation has completed.
		//
		// Returns:
		//     true if the operation is complete; otherwise, false.
		public bool IsCompleted
		{
			get { return true; }
		}

		// Summary:
		//     Gets a user-defined object that qualifies or contains information about an
		//     asynchronous operation.
		//
		// Returns:
		//     A user-defined object that qualifies or contains information about an asynchronous
		//     operation.
		public object AsyncState
		{
			get { return _stateObject; }
		}
	}

	#endregion

	#region UDTSocketException

	public sealed class UDTSocketException : Exception
	{

		private int _errorCode;

		public UDTSocketException(int errorCode, string errorMessage)
			: base(errorMessage)
		{
			_errorCode = errorCode;
		}

		public UDTSocketException()
			: base(API_GetLastErrorMessage())
		{
			_errorCode = API_GetLastErrorCode();
		}

		public int ErrorCode
		{
			get
			{
				return _errorCode;
			}
			set { _errorCode = value; }
		}

		[DllImport("transport.dll", EntryPoint = "UDTGetlasterrorCode")]
		private static extern int API_GetLastErrorCode();

		[DllImport("transport.dll", EntryPoint = "UDTGetlasterrorMessage")]
		private static extern string API_GetLastErrorMessage();
	}

	#endregion

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -