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

📄 socket.cs

📁 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的
💻 CS
📖 第 1 页 / 共 3 页
字号:
/* * Socket.cs - Implementation of the "System.Net.Sockets.Socket" class. * * Copyright (C) 2003  Southern Storm Software, Pty Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */namespace System.Net.Sockets{using Platform;using System;using System.Collections;using System.Security;using System.Threading;public class Socket : IDisposable{	// Internal state.	private IntPtr handle;	private AddressFamily family;	private SocketType socketType;	private ProtocolType protocol;	private bool blocking;	private bool connected;	private EndPoint localEP;	private EndPoint remoteEP;	private Object readLock;	// Invalid socket handle.	private static readonly IntPtr InvalidHandle =		SocketMethods.GetInvalidHandle();	// Constructor.	public Socket(AddressFamily addressFamily, SocketType socketType,				  ProtocolType protocolType)			{				// Validate the parameters.				if(addressFamily == AddressFamily.Unspecified)				{					addressFamily = AddressFamily.InterNetwork;				}				else if(!SocketMethods.AddressFamilySupported							((int)addressFamily))				{					throw new SocketException(Errno.EINVAL);				}				if(socketType == SocketType.Stream)				{					if(protocolType == ProtocolType.Unspecified)					{						if(addressFamily == AddressFamily.InterNetwork ||						   addressFamily == AddressFamily.InterNetworkV6)						{							protocolType = ProtocolType.Tcp;						}					}					else if(protocolType != ProtocolType.Tcp)					{						throw new SocketException(Errno.EPROTONOSUPPORT);					}				}				else if(socketType == SocketType.Dgram)				{					if(protocolType == ProtocolType.Unspecified)					{						if(addressFamily == AddressFamily.InterNetwork ||						   addressFamily == AddressFamily.InterNetworkV6)						{							protocolType = ProtocolType.Udp;						}					}					else if(protocolType != ProtocolType.Udp)					{						throw new SocketException(Errno.EPROTONOSUPPORT);					}				}				else				{					throw new SocketException(Errno.ESOCKTNOSUPPORT);				}				// Initialize the local state.				this.handle = InvalidHandle;				this.family = addressFamily;				this.socketType = socketType;				this.protocol = protocolType;				this.blocking = true;				this.connected = false;				this.localEP = null;				this.remoteEP = null;				this.readLock = new Object();				// Attempt to create the socket.  This may bail out for				// some address families, even if "AddressFamilySupported"				// returned true.  This can happen, for example, if the user				// space definitions are available for IrDA, but the kernel				// drivers are not.  "AddressFamilySupported" may not be				// able to detect the kernel capabilities on all platforms.				if(!SocketMethods.Create((int)addressFamily, (int)socketType,										 (int)protocolType, out handle))				{					throw new SocketException(SocketMethods.GetErrno());				}			}	private Socket(AddressFamily addressFamily, SocketType socketType,				   ProtocolType protocolType, IntPtr handle, bool blocking,				   EndPoint remoteEP)			{				// Set up for a new socket that has just been accepted.				this.handle = handle;				this.family = addressFamily;				this.socketType = socketType;				this.protocol = protocolType;				this.blocking = blocking;				this.connected = true;				this.localEP = null;				this.remoteEP = remoteEP;				this.readLock = new Object();			}	// Destructor.	~Socket()			{				Dispose(false);			}	// Implement the IDisposable interface.	void IDisposable.Dispose()			{				Dispose(true);				GC.SuppressFinalize(this);			}	// Accept an incoming connection on this socket.	public Socket Accept()			{				IntPtr currentHandle;				IntPtr newHandle;				EndPoint remoteEP;				// Get the socket handle, synchronized against "Close".				lock(this)				{					// Bail out if the socket has been closed.					if(handle == InvalidHandle)					{						throw new ObjectDisposedException							(S._("Exception_Disposed"));					}					currentHandle = handle;				}				// Create the sockaddr buffer from the local end point.				byte[] addrReturn = LocalEndPoint.Serialize().Array;				Array.Clear(addrReturn, 0, addrReturn.Length);				// Accept a new connection on the socket.  We do this outside				// of the lock's protection so that multiple threads can				// wait for incoming connections on the same socket.				if(!SocketMethods.Accept					  (currentHandle, addrReturn, out newHandle))				{					throw new SocketException(SocketMethods.GetErrno());				}				// Create the end-point object for the remote side.				remoteEP = LocalEndPoint.Create(new SocketAddress(addrReturn));				// Create and return a new socket object.				return new Socket(family, socketType, protocol,								  newHandle, blocking, remoteEP);			}	// Asynchronous operation types.	private enum AsyncOperation	{		Accept,		Connect,		Receive,		ReceiveFrom,		Send,		SendTo	}; // enum AsyncOperation	// Asynchronous operation control class.	private sealed class AsyncControl : IAsyncResult	{		// Internal state.		private WaitHandle waitHandle;		private bool completedSynchronously;		private bool completed;		private AsyncOperation operation;		private AsyncCallback callback;		private Object state;		private Socket socket;		private byte[] buffer;		private int offset;		private int count;		private SocketFlags flags;		public int result;		public Socket acceptResult;		public EndPoint remoteEP;		private Exception exception;		// Constructor.		public AsyncControl(AsyncCallback callback, Object state,							Socket socket, byte[] buffer, int offset,							int count, SocketFlags flags, EndPoint remoteEP,							AsyncOperation operation)				{				#if ECMA_COMPAT					this.waitHandle = SocketMethods.CreateManualResetEvent();				#else					this.waitHandle = new ManualResetEvent(false);				#endif					this.completedSynchronously = false;					this.completed = false;					this.operation = operation;					this.callback = callback;					this.state = state;					this.socket = socket;					this.buffer = buffer;					this.offset = offset;					this.count = count;					this.flags = flags;					this.result = -1;					this.acceptResult = null;					this.remoteEP = remoteEP;					this.exception = null;				}		// Run the operation thread.		private void Run(IAsyncResult state)				{					try					{						switch(operation)						{							case AsyncOperation.Accept:							{								acceptResult = socket.Accept();							}							break;							case AsyncOperation.Connect:							{								socket.Connect(remoteEP);							}							break;							case AsyncOperation.Receive:							{								result = socket.Receive									(buffer, offset, count, flags);							}							break;							case AsyncOperation.ReceiveFrom:							{								result = socket.ReceiveFrom									(buffer, offset, count, flags,									 ref remoteEP);							}							break;							case AsyncOperation.Send:							{								result = socket.Send									(buffer, offset, count, flags);							}							break;							case AsyncOperation.SendTo:							{								result = socket.SendTo									(buffer, offset, count, flags, remoteEP);							}							break;						}					}					catch(Exception e)					{						// Save the exception to be thrown in EndXXX.						exception = e;					}					completed = true;					if(callback != null)					{						callback(this);					}					if(waitHandle != null)					{				#if ECMA_COMPAT						SocketMethods.WaitHandleSet(waitHandle);				#else						((ManualResetEvent)waitHandle).Set();				#endif					}				}		// Start the async thread, or perform the operation synchronously.		public void Start()				{					if(SocketMethods.CanStartThreads())					{						SocketMethods.QueueCompletionItem							(new AsyncCallback(Run), this);					}					else					{						completedSynchronously = true;						Run(null);					}				}		// Wait for an asynchronous operation to complete.		// Also handles exceptions that were thrown by the operation.		public void Wait(Socket check, AsyncOperation oper)				{					if(socket != check || operation != oper)					{						throw new ArgumentException(S._("Arg_InvalidAsync"));					}					WaitHandle handle = waitHandle;					if(handle != null)					{						if(!completed)						{							handle.WaitOne();						}						((IDisposable)handle).Dispose();					}					waitHandle = null;					if(exception != null)					{						throw exception;					}				}		// Implement the IAsyncResult interface.		public Object AsyncState				{					get					{						return state;					}				}		public WaitHandle AsyncWaitHandle				{					get					{						return waitHandle;					}				}		public bool CompletedSynchronously				{					get					{						return completedSynchronously;					}				}		public bool IsCompleted				{					get					{						return completed;					}				}	}; // class AsyncControl	// Begin an asynchronous operation to accept an incoming connection.	public IAsyncResult BeginAccept(AsyncCallback callback, Object state)			{				// Create the result object.				AsyncControl async = new AsyncControl					(callback, state, this, null, 0, 0,					 SocketFlags.None, null, AsyncOperation.Accept);				// Start the background process.				async.Start();				return async;			}	// End an asynchronous accept operation.	public Socket EndAccept(IAsyncResult asyncResult)			{				if(asyncResult == null)				{					throw new ArgumentNullException("asyncResult");				}				else if(!(asyncResult is AsyncControl))				{					throw new ArgumentException(S._("Arg_InvalidAsync"));				}				else				{					AsyncControl async = (AsyncControl)asyncResult;					async.Wait(this, AsyncOperation.Accept);					return async.acceptResult;				}			}	// Begin an asynchronous operation to connect on this socket.	public IAsyncResult BeginConnect(EndPoint remoteEP,									 AsyncCallback callback,									 Object state)			{				// Validate the parameters.				if(remoteEP == null)				{					throw new ArgumentNullException("remoteEP");				}				else if(remoteEP.AddressFamily != family)				{					throw new SocketException(Errno.EINVAL);				}				// Create the result object.				AsyncControl async = new AsyncControl					(callback, state, this, null, 0, 0,					 SocketFlags.None, remoteEP, AsyncOperation.Connect);				// Start the background process.				async.Start();				return async;			}	// End an asynchronous connect operation.	public void EndConnect(IAsyncResult asyncResult)			{				if(asyncResult == null)				{					throw new ArgumentNullException("asyncResult");				}				else if(!(asyncResult is AsyncControl))				{					throw new ArgumentException(S._("Arg_InvalidAsync"));				}				else				{					((AsyncControl)asyncResult).Wait						(this, AsyncOperation.Connect);				}			}	// Begin an asynchronous operation to receive on this socket.	public IAsyncResult BeginReceive(byte[] buffer, int offset, int size,									 SocketFlags socketFlags,									 AsyncCallback callback,									 Object state)			{				// Validate the parameters.				ValidateBuffer(buffer, offset, size);				// Create the result object.				AsyncControl async = new AsyncControl					(callback, state, this, buffer, offset, size,					 socketFlags, null, AsyncOperation.Receive);				// Start the background process.				async.Start();				return async;			}	// End an asynchronous receive operation.	public int EndReceive(IAsyncResult asyncResult)			{				if(asyncResult == null)				{					throw new ArgumentNullException("asyncResult");				}				else if(!(asyncResult is AsyncControl))				{					throw new ArgumentException(S._("Arg_InvalidAsync"));				}				else				{					AsyncControl async = (AsyncControl)asyncResult;					async.Wait(this, AsyncOperation.Receive);					return async.result;				}			}	// Begin an asynchronous operation to receive from this socket.	public IAsyncResult BeginReceiveFrom(byte[] buffer, int offset, int size,									 	 SocketFlags socketFlags,										 ref EndPoint remoteEP,									 	 AsyncCallback callback,									 	 Object state)			{				// Validate the parameters.				ValidateBuffer(buffer, offset, size);				if(remoteEP == null)				{					throw new ArgumentNullException("remoteEP");				}				else if(remoteEP.AddressFamily != family)				{					throw new SocketException(Errno.EINVAL);				}				// Create the result object.				AsyncControl async = new AsyncControl					(callback, state, this, buffer, offset, size,					 socketFlags, remoteEP, AsyncOperation.ReceiveFrom);				// Start the background process.				async.Start();				return async;			}	// End an asynchronous receive from operation.	public int EndReceiveFrom(IAsyncResult asyncResult, ref EndPoint endPoint)			{				if(asyncResult == null)				{					throw new ArgumentNullException("asyncResult");				}				else if(!(asyncResult is AsyncControl))				{					throw new ArgumentException(S._("Arg_InvalidAsync"));				}				else				{					AsyncControl async = (AsyncControl)asyncResult;					async.Wait(this, AsyncOperation.ReceiveFrom);					endPoint = async.remoteEP;					return async.result;				}			}	// Begin an asynchronous operation to send on this socket.	public IAsyncResult BeginSend(byte[] buffer, int offset, int size,								  SocketFlags socketFlags,								  AsyncCallback callback,								  Object state)			{				// Validate the parameters.				ValidateBuffer(buffer, offset, size);				// Create the result object.				AsyncControl async = new AsyncControl					(callback, state, this, buffer, offset, size,					 socketFlags, null, AsyncOperation.Send);				// Start the background process.				async.Start();				return async;			}	// End an asynchronous send operation.	public int EndSend(IAsyncResult asyncResult)			{				if(asyncResult == null)				{					throw new ArgumentNullException("asyncResult");				}				else if(!(asyncResult is AsyncControl))				{					throw new ArgumentException(S._("Arg_InvalidAsync"));				}				else				{					AsyncControl async = (AsyncControl)asyncResult;					async.Wait(this, AsyncOperation.Send);					return async.result;				}			}	// Begin an asynchronous operation to send from this socket.	public IAsyncResult BeginSendTo(byte[] buffer, int offset, int size,								 	SocketFlags socketFlags,									EndPoint remoteEP,								 	AsyncCallback callback,								 	Object state)			{				// Validate the parameters.				ValidateBuffer(buffer, offset, size);				if(remoteEP == null)				{					throw new ArgumentNullException("remoteEP");				}				else if(remoteEP.AddressFamily != family)				{					throw new SocketException(Errno.EINVAL);				}				// Create the result object.				AsyncControl async = new AsyncControl					(callback, state, this, buffer, offset, size,					 socketFlags, remoteEP, AsyncOperation.SendTo);				// Start the background process.				async.Start();				return async;			}	// End an asynchronous send to operation.	public int EndSendTo(IAsyncResult asyncResult)			{				if(asyncResult == null)				{					throw new ArgumentNullException("asyncResult");				}				else if(!(asyncResult is AsyncControl))				{					throw new ArgumentException(S._("Arg_InvalidAsync"));				}				else

⌨️ 快捷键说明

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