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 + -
显示快捷键?