socket.cs

来自「没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没」· CS 代码 · 共 1,874 行 · 第 1/3 页

CS
1,874
字号
				{					AsyncControl async = (AsyncControl)asyncResult;					async.Wait(this, AsyncOperation.SendTo);					return async.result;				}			}	// Bind this socket to a specific end-point.	public void Bind(EndPoint localEP)			{				// Validate the parameter.				if(localEP == null)				{					throw new ArgumentNullException("localEP");				}				else if(localEP.AddressFamily != family)				{					throw new SocketException(Errno.EINVAL);				}				// Convert the end point into a sockaddr buffer.				byte[] addr = localEP.Serialize().Array;				// Lock down the socket object while we do the bind.				lock(this)				{					// Bail out if the socket has been closed.					if(handle == InvalidHandle)					{						throw new ObjectDisposedException							(S._("Exception_Disposed"));					}					// Bind the address to the socket.					if(!SocketMethods.Bind(handle, addr))					{						throw new SocketException(SocketMethods.GetErrno());					}					// Record the local end point for later.					this.localEP = localEP;				}			}	// Close this socket.	public void Close()			{				Dispose(true);				GC.SuppressFinalize(this);			}	// Connect to a remote end-point.	public void Connect(EndPoint remoteEP)			{				// Validate the parameter.				if(remoteEP == null)				{					throw new ArgumentNullException("remoteEP");				}				else if(remoteEP.AddressFamily != family)				{					throw new SocketException(Errno.EINVAL);				}				// Convert the end point into a sockaddr buffer.				byte[] addr = remoteEP.Serialize().Array;				// Lock down the socket object while we do the connect.				lock(this)				{					// Bail out if the socket has been closed.					if(handle == InvalidHandle)					{						throw new ObjectDisposedException							(S._("Exception_Disposed"));					}					// Connect to the foreign location.					if(!SocketMethods.Connect(handle, addr))					{						throw new SocketException(SocketMethods.GetErrno());					}					connected = true;					this.remoteEP = remoteEP;				}			}	// Dispose this socket.	protected virtual void Dispose(bool disposing)			{				lock(this)				{					if(handle != InvalidHandle)					{						SocketMethods.Close(handle);						handle = InvalidHandle;					}				}			}	// Get the hash code for this object.	public override int GetHashCode()			{				return base.GetHashCode();			}	// Get a raw numeric socket option.	private int GetSocketOptionRaw(SocketOptionLevel optionLevel,								   SocketOptionName optionName)			{				int optionValue;				lock(this)				{					if(handle == InvalidHandle)					{						throw new ObjectDisposedException							(S._("Exception_Disposed"));					}					if(!SocketMethods.GetSocketOption							(handle, (int)optionLevel, (int)optionName,							 out optionValue))					{						throw new SocketException(SocketMethods.GetErrno());					}					return optionValue;				}			}	// Get an option on this socket.	public Object GetSocketOption(SocketOptionLevel optionLevel,								  SocketOptionName optionName)			{				bool enabled;				int seconds;				// Validate the option information to ensure that the				// caller is not trying to get something that is insecure.				if(optionLevel == SocketOptionLevel.Socket)				{					if(optionName == SocketOptionName.KeepAlive ||					   optionName == SocketOptionName.ReceiveTimeout ||					   optionName == SocketOptionName.SendTimeout ||					   optionName == SocketOptionName.ReceiveBuffer ||					   optionName == SocketOptionName.SendBuffer ||					   optionName == SocketOptionName.ReuseAddress)					{						return GetSocketOptionRaw(optionLevel, optionName);					}					if(optionName == SocketOptionName.DontLinger)					{						// Get the linger information and test it.						lock(this)						{							if(handle == InvalidHandle)							{								throw new ObjectDisposedException									(S._("Exception_Disposed"));							}							if(!SocketMethods.GetLingerOption									(handle, out enabled, out seconds))							{								throw new SocketException									(SocketMethods.GetErrno());							}							return ((enabled && seconds == 0) ? 1 : 0);						}					}					if(optionName == SocketOptionName.Linger)					{						// Get the linger information.						lock(this)						{							if(handle == InvalidHandle)							{								throw new ObjectDisposedException									(S._("Exception_Disposed"));							}							if(!SocketMethods.GetLingerOption									(handle, out enabled, out seconds))							{								throw new SocketException									(SocketMethods.GetErrno());							}							return new LingerOption(enabled, seconds);						}					}					if(optionName == SocketOptionName.ExclusiveAddressUse)					{						// Flip the option and turn it into "ReuseAddress".						int reuse = GetSocketOptionRaw							(optionLevel, SocketOptionName.ReuseAddress);						return ((reuse != 0) ? 0 : 1);					}					if(optionName == SocketOptionName.Type)					{						// Return the socket type.						return (int)socketType;					}				}				else if(optionLevel == SocketOptionLevel.Tcp)				{					if(optionName == SocketOptionName.NoDelay ||					   optionName == SocketOptionName.Expedited)					{						return GetSocketOptionRaw(optionLevel, optionName);					}				}				else if(optionLevel == SocketOptionLevel.Udp)				{					if(optionName == SocketOptionName.NoChecksum ||					   optionName == SocketOptionName.ChecksumCoverage)					{						return GetSocketOptionRaw(optionLevel, optionName);					}				}				else if(optionLevel == SocketOptionLevel.IP)				{					if(optionName == SocketOptionName.AddMembership ||					   optionName == SocketOptionName.DropMembership)					{						// Get the contents of the multicast membership set.						byte[] group;						byte[] mcint;						lock(this)						{							if(handle == InvalidHandle)							{								throw new ObjectDisposedException									(S._("Exception_Disposed"));							}							group = new byte [32];							mcint = new byte [32];							if(!SocketMethods.GetMulticastOption									(handle, (int)family, (int)optionName,									 group, mcint))							{								throw new SocketException									(SocketMethods.GetErrno());							}							return new MulticastOption								((new SocketAddress(group)).IPAddress,								 (new SocketAddress(mcint)).IPAddress);						}					}				}				throw new SecurityException(S._("Arg_SocketOption"));			}	public void GetSocketOption(SocketOptionLevel optionLevel,								SocketOptionName optionName,								byte[] optionValue)			{				// This version is not portable - do not use.				throw new SecurityException(S._("Arg_SocketOption"));			}	public byte[] GetSocketOption(SocketOptionLevel optionLevel,								  SocketOptionName optionName,								  int optionLength)			{				// Check for the IrDA device discovery option.				if(optionLevel == (SocketOptionLevel)255 &&				   optionName == (SocketOptionName)16)				{					lock(this)					{						if(handle == InvalidHandle)						{							throw new ObjectDisposedException								(S._("Exception_Disposed"));						}						else if(family != AddressFamily.Irda)						{							throw new SocketException(Errno.EINVAL);						}						byte[] data = new byte [optionLength];						if(!SocketMethods.DiscoverIrDADevices(handle, data))						{							throw new SocketException								(SocketMethods.GetErrno());						}						return data;					}				}				// Everything else is non-portable - do not use.				throw new SecurityException(S._("Arg_SocketOption"));			}	// Perform an "ioctl" operation on this socket.	public int IOControl(int ioControlCode, byte[] optionInValue,						 byte[] optionOutValue)			{				// We don't support any "ioctl" operations in this				// implementation because they aren't portable or they				// are inherently insecure (e.g. changing process groups).				// The two most interesting ones (FIONBIO and FIONREAD)				// can be accessed using "Blocking" and "Available" instead.				throw new SocketException(Errno.EINVAL);			}	// Perform a listen operation on this socket.	public void Listen(int backlog)			{				lock(this)				{					// Bail out if the socket has been closed.					if(handle == InvalidHandle)					{						throw new ObjectDisposedException							(S._("Exception_Disposed"));					}					// Perform a listen on the socket.					if(!SocketMethods.Listen(handle, backlog))					{						throw new SocketException(SocketMethods.GetErrno());					}				}			}	// Poll the select status of the socket.	public bool Poll(int microSeconds, SelectMode mode)			{				IntPtr[] array;				int result;				// Create an array that contains the socket's handle.				array = new IntPtr [1];				array[0] = GetHandle(this);				// Perform the select.				switch(mode)				{					case SelectMode.SelectRead:					{ 						result = SocketMethods.Select							(array, null, null, (long)microSeconds);					}					break;					case SelectMode.SelectWrite:					{						result = SocketMethods.Select							(null, array, null, (long)microSeconds);					}					break;					case SelectMode.SelectError:					{						result = SocketMethods.Select							(null, null, array, (long)microSeconds);					}					break;					default:					{						throw new NotSupportedException							(S._("NotSupp_SelectMode"));					}					// Not reached.				}				// Decode the result and return.				if(result == 0)				{					return false;				}				else if(result < 0)				{					throw new SocketException(SocketMethods.GetErrno());				}				else				{					return true;				}			}	// Receive data on this socket.	public int Receive(byte[] buffer, int offset, int size,					   SocketFlags socketFlags)			{				int result;				// Validate the arguments.				ValidateBuffer(buffer, offset, size);				// Perform the receive operation.				lock(readLock)				{					if(handle == InvalidHandle)					{						throw new ObjectDisposedException							(S._("Exception_Disposed"));					}					result = SocketMethods.Receive						(handle, buffer, offset, size, (int)socketFlags);					if(result < 0)					{						throw new SocketException(SocketMethods.GetErrno());					}					else					{						return result;					}				}			}	public int Receive(byte[] buffer, int size, SocketFlags socketFlags)			{				return Receive(buffer, 0, size, socketFlags);			}	public int Receive(byte[] buffer, SocketFlags socketFlags)			{				if(buffer == null)				{					throw new ArgumentNullException("buffer");				}				return Receive(buffer, 0, buffer.Length, socketFlags);			}	public int Receive(byte[] buffer)			{				if(buffer == null)				{					throw new ArgumentNullException("buffer");				}				return Receive(buffer, 0, buffer.Length, SocketFlags.None);			}	// Receive data on this socket and record where it came from.	public int ReceiveFrom(byte[] buffer, int offset, int size,					       SocketFlags socketFlags, ref EndPoint remoteEP)			{				int result;				byte[] addrReturn;				// Validate the arguments.				ValidateBuffer(buffer, offset, size);				if(remoteEP == null)				{					throw new ArgumentNullException("remoteEP");				}				else if(remoteEP.AddressFamily != family)				{					throw new SocketException(Errno.EINVAL);				}				// Create a sockaddr buffer to write the address into.				addrReturn = remoteEP.Serialize().Array;				Array.Clear(addrReturn, 0, addrReturn.Length);				// Perform the receive operation.				lock(readLock)				{					if(handle == InvalidHandle)					{						throw new ObjectDisposedException							(S._("Exception_Disposed"));					}					result = SocketMethods.ReceiveFrom						(handle, buffer, offset, size,						 (int)socketFlags, addrReturn);					if(result < 0)					{						throw new SocketException(SocketMethods.GetErrno());					}					else					{						remoteEP = remoteEP.Create							(new SocketAddress(addrReturn));						return result;					}				}			}	public int ReceiveFrom(byte[] buffer, int size, SocketFlags socketFlags,						   ref EndPoint remoteEP)			{				return ReceiveFrom(buffer, 0, size, socketFlags, ref remoteEP);			}	public int ReceiveFrom(byte[] buffer, SocketFlags socketFlags,						   ref EndPoint remoteEP)			{				if(buffer == null)				{					throw new ArgumentNullException("buffer");				}				return ReceiveFrom(buffer, 0, buffer.Length,								   socketFlags, ref remoteEP);			}	public int ReceiveFrom(byte[] buffer, ref EndPoint remoteEP)			{				if(buffer == null)				{					throw new ArgumentNullException("buffer");				}				return ReceiveFrom(buffer, 0, buffer.Length,								   SocketFlags.None, ref remoteEP);			}	// Perform a select operation on a group of sockets.	public static void Select(IList checkRead, IList checkWrite,							  IList checkError, int microSeconds)			{				int posn, posn2, result;				IntPtr[] readArray;				IntPtr[] writeArray;				IntPtr[] errorArray;				// Validate the parameters.				if((checkRead == null || checkRead.Count == 0) &&				   (checkWrite == null || checkWrite.Count == 0) &&				   (checkError == null || checkError.Count == 0))				{					throw new ArgumentNullException("all");				}				// Convert the lists into socket handle arrays.				if(checkRead != null)				{					readArray = new IntPtr [checkRead.Count];					for(posn = 0; posn < checkRead.Count; ++posn)					{						readArray[posn] = GetHandle(checkRead[posn]);					}				}				else				{					readArray = null;				}				if(checkWrite != null)				{					writeArray = new IntPtr [checkWrite.Count];					for(posn = 0; posn < checkWrite.Count; ++posn)					{						writeArray[posn] = GetHandle(checkWrite[posn]);					}				}				else				{					writeArray = null;				}				if(checkError != null)				{					errorArray = new IntPtr [checkError.Count];					for(posn = 0; posn < checkError.Count; ++posn)					{						errorArray[posn] = GetHandle(checkError[posn]);					}				}				else				{					errorArray = null;				}				// Perform the select.				result = SocketMethods.Select					(readArray, writeArray, errorArray, (long)microSeconds);				// Decode the result.  If the list is fixed-size,				// then we set the removed elements to null; otherwise				// we remove the elements with "IList.RemoveAt".				if(result == 0)				{					// A timeout occurred, so clear all return sets.					if(checkRead != null)					{						if(!(checkRead.IsFixedSize))						{							checkRead.Clear();						}						else						{							for(posn = 0; posn < checkRead.Count; ++posn)							{								checkRead[posn] = null;							}						}					}					if(checkWrite != null)					{						if(!(checkWrite.IsFixedSize))						{							checkWrite.Clear();						}						else						{							for(posn = 0; posn < checkWrite.Count; ++posn)							{								checkWrite[posn] = null;							}						}					}					if(checkError != null)					{						if(!(checkError.IsFixedSize))						{							checkError.Clear();						}						else						{							for(posn = 0; posn < checkError.Count; ++posn)							{								checkError[posn] = null;							}						}					}					return;				}				else if(result < 0)				{					// Some kind of error occurred.					throw new SocketException(SocketMethods.GetErrno());				}				// Ordinary return: update the sets to reflect the result.				if(checkRead != null)				{					if(!(checkRead.IsFixedSize))					{						posn2 = 0;						for(posn = 0; posn < readArray.Length; ++posn)						{							if(readArray[posn] == InvalidHandle)							{								checkRead.RemoveAt(posn2);							}							else							{

⌨️ 快捷键说明

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