www.pudn.com > SharpDownload(FTP¼°WEBÏÂÔØ).zip > ProtocolClient.cs


using System; 
using System.Net; 
using System.IO; 
using System.Text; 
using System.Net.Sockets; 
using System.Diagnostics; 
using System.Runtime.Remoting; 
using System.Runtime.Remoting.Messaging; 
 
namespace SharpDownload 
{ 
	///  
	/// Abstract protocol client class 
	///  
	public abstract class ProtocolClient 
	{ 
 
		///  
		/// Protocol exception class 
		///  
		public class ProtocolException : Exception 
		{ 
			public ProtocolException(string message) : base(message){} 
			public ProtocolException(string message, Exception innerException) : base(message,innerException){} 
		} 
 
		public class ProtocolCommandException : ApplicationException 
		{ 
			private FileDownload.FileDownloadCommandEnum command = FileDownload.FileDownloadCommandEnum.NoCommand; 
			public ProtocolCommandException(FileDownload.FileDownloadCommandEnum Command) 
			{ 
				command = Command; 
			} 
			public FileDownload.FileDownloadCommandEnum Command 
			{ 
				get 
				{ 
					return command; 
				} 
			} 
		} 
 
		public enum DownloadResult 
		{ 
			Error, 
			Paused, 
			Cancelled, 
			Finished 
		} 
 
		protected static int BUFFER_SIZE = 512; 
		protected static Encoding ASCII = Encoding.ASCII; 
 
		protected bool verboseDebugging = false; 
 
		// defaults 
		protected string server = string.Empty; 
		protected string remotePath = string.Empty; 
		protected string username = string.Empty; 
		protected string password = string.Empty; 
		protected string message = null; 
		protected string result = null; 
 
		protected string[] fullMessage = null; 
 
		protected int port = 0; 
		protected int bytes = 0; 
		protected int resultCode = 0; 
 
		protected bool loggedin = false; 
		protected bool binMode = false; 
 
		protected Byte[] buffer = new Byte[BUFFER_SIZE]; 
		protected Socket clientSocket = null; 
 
		protected int timeoutSeconds = 60; 
 
		private string MODULE_NAME = "ProtocolClient"; 
 
		///  
		/// Default constructor 
		///  
		public ProtocolClient() 
		{ 
		} 
 
		///  
		/// Overloaded constructor 
		///  
		///  
		///  
		///  
		public ProtocolClient(string server, string username, string password) 
		{ 
			this.Server = server; 
			this.Username = username; 
			this.Password = password; 
		} 
		///  
		/// Overloaded constructor 
		///  
		///  
		///  
		///  
		///  
		///  
		public ProtocolClient(string server, string username, string password, int timeoutSeconds, int port) 
		{ 
			this.server = server; 
			this.username = username; 
			this.password = password; 
			this.timeoutSeconds = timeoutSeconds; 
			this.port = port; 
		} 
 
		///  
		/// Simple factory patter 
		/// Returns the appropriate protocol client dependent on the protocol passed 
		///  
		/// type of protocol client to get 
		/// protocol client sub-class 
		public static ProtocolClient GetProtocolClient(string protocol) 
		{ 
			switch (protocol) 
			{ 
				case "ftp://": 
					return new FtpClient(); 
				case "http://": 
					return new HttpClient(); 
				default: 
					throw new ApplicationException("Unknown protocol: " + protocol + "."); 
			} 
		} 
 
		///  
		/// Return a new protocol client 
		///  
		/// url to check 
		/// url to check 
		/// ProtocolClient sub-class 
		public static ProtocolClient GetProtocolClient(string protocol, DownloadInfo downloadInfo) 
		{ 
			ProtocolClient client = ProtocolClient.GetProtocolClient(protocol); 
			client.Server = downloadInfo.ServerAddress; 
			client.Port = downloadInfo.Port; 
			return client; 
		} 
 
		///  
		/// Return a new protocol client 
		///  
		/// Download info 
		/// ProtocolClient sub-class 
		public static ProtocolClient GetProtocolClient(DownloadInfo downloadInfo) 
		{ 
			ProtocolClient client = ProtocolClient.GetProtocolClient(downloadInfo.Protocol); 
			client.Server = downloadInfo.ServerAddress; 
			client.Port = downloadInfo.Port; 
			client.Username = downloadInfo.UserName; 
			client.Password = downloadInfo.Password; 
			return client; 
		} 
 
		///  
		/// Display all communications to the debug log 
		///  
		public bool VerboseDebugging 
		{ 
			get 
			{ 
				return this.verboseDebugging; 
			} 
			set 
			{ 
				this.verboseDebugging = value; 
			} 
		} 
		///  
		/// Remote server port. 
		///  
		public int Port 
		{ 
			get 
			{ 
				return this.port; 
			} 
			set 
			{ 
				this.port = value; 
			} 
		} 
 
		///  
		/// Timeout waiting for a response from server, in seconds. 
		///  
		public int Timeout 
		{ 
			get 
			{ 
				return this.timeoutSeconds; 
			} 
			set 
			{ 
				this.timeoutSeconds = value; 
			} 
		} 
 
		///  
		/// Gets and Sets the name of the server. 
		///  
		///  
		public string Server 
		{ 
			get 
			{ 
				return this.server; 
			} 
			set 
			{ 
				this.server = value; 
			} 
		} 
 
		///  
		/// Gets and Sets the port number. 
		///  
		public int RemotePort 
		{ 
			get 
			{ 
				return this.port; 
			} 
			set 
			{ 
				this.port = value; 
			} 
		} 
 
		///  
		/// GetS and Sets the remote directory. 
		///  
		public string RemotePath 
		{ 
			get 
			{ 
				return this.remotePath; 
			} 
			set 
			{ 
				this.remotePath = value; 
			} 
 
		} 
 
		///  
		/// Gets and Sets the username. 
		///  
		public string Username 
		{ 
			get 
			{ 
				return this.username; 
			} 
			set 
			{ 
				this.username = value; 
			} 
		} 
 
		///  
		/// Gets and Set the password. 
		///  
		public string Password 
		{ 
			get 
			{ 
				return this.password; 
			} 
			set 
			{ 
				this.password = value; 
			} 
		} 
 
		///  
		/// Return whether session is logged in 
		///  
		public bool IsLoggedIn 
		{ 
			get 
			{ 
				return loggedin; 
			} 
		} 
 
		///  
		/// Copy a larger array's elements to a smaller array. 
		/// Elements out of the smaller arrays bounds are ignored. 
		///  
		/// The larger array 
		/// Number of elements to copy to the smaller array 
		/// Smaller array 
		protected byte[] CopyToSmallArray(byte[] bigArray, int elementsToCopy) 
		{ 
			Byte[] smallArray = new Byte[elementsToCopy-1]; 
			for (int i=0;i 
		/// Copy a larger array's elements to a smaller array. 
		/// Elements out of the smaller arrays bounds are ignored. 
		///  
		/// The larger array 
		/// Number of elements to copy to the smaller array 
		/// Number of elements to copy to the smaller array 
		/// Smaller array 
		protected byte[] CopyToSmallArray(byte[] bigArray, int elementsToCopy, int startIndex) 
		{ 
			Byte[] smallArray = new Byte[elementsToCopy]; 
			for (int i=startIndex;i 
		/// Overloaded function - creates a tcp data socket for the data download 
		///  
		/// Connected socket 
		protected Socket createDataSocket() 
		{ 
			return createDataSocket(this.Server, this.Port); 
		} 
 
		///  
		/// Overloaded function - creates a tcp data socket for the data download 
		///  
		/// Connected socket 
		protected Socket createDataSocket(string ipAddress, int port) 
		{ 
			Socket socket = null; 
			IPHostEntry iphe = null; 
 
			// Try and open a connection to the server 
			try 
			{ 
 
				iphe = Dns.Resolve(ipAddress); 
 
				// Loop through the AddressList to obtain the supported AddressFamily. This is to avoid 
				// an exception to be thrown if the host IP Address is not compatible with the address family 
				// (typical in the IPv6 case). 
				foreach(IPAddress ipad in iphe.AddressList) 
				{ 
					IPEndPoint ipe = new IPEndPoint(ipad, port); 
 
					Socket tmpS =  
						new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp); 
 
					tmpS.Connect(ipe); 
 
					if(tmpS.Connected) 
					{ 
						socket = tmpS; 
						break; 
					} 
					else 
						continue; 
				} 
 
			} 
			catch(Exception ex) 
			{ 
				// doubtful 
				if ( this.clientSocket != null && this.clientSocket.Connected ) this.clientSocket.Close(); 
 
				throw new ProtocolException("Couldn't connect to remote server",ex); 
			} 
 
			// Check if we have a valid connection 
			if (socket==null) 
			{ 
				throw new ProtocolException("Couldn't connect to remote server"); 
			} 
 
			Debug.WriteLine("Connected to " + this.server, MODULE_NAME ); 
 
			return socket; 
		} 
 
		///  
		/// Gets a file stream to write downloaded output to. 
		///  
		/// local file name to create 
		/// remote file name, used for local file name when no local name provided 
		/// open FileStream object 
		protected FileStream GetLocalFileStream(string locFileName, string remFileName) 
		{ 
			// Check if the local filename was passed 
			if (locFileName.Equals("")) 
			{ 
				// Set local filename to name of remote file 
				locFileName = remFileName; 
			} 
 
			// Check if the file already exists 
			FileStream output = null; 
			if ( !File.Exists(locFileName) ) 
			{ 
				// Create a new file 
				output = File.Create(locFileName); 
			} 
			else 
			{ 
				// Append output to the existing file 
				output = new FileStream(locFileName, FileMode.Open); 
			} 
 
			return output; 
		} 
 
		///  
		/// Resets the download buffer 
		///  
		public void ResetBuffer() 
		{ 
			this.buffer = new Byte[BUFFER_SIZE]; 
		} 
 
		public abstract FileDownload.FileDownloadCommandEnum Command 
		{ 
			get; 
			set; 
		} 
 
		public abstract bool CanResume(); 
 
		public abstract bool CanResume(string remFileName); 
 
		public abstract void Close(); 
 
		public abstract void Login(); 
 
		public abstract long GetFileSize(string remFileName); 
 
		public abstract void StopDownload(); 
 
		public abstract DownloadResult Download(string remFileName); 
 
		public abstract DownloadResult Download(string remFileName, bool resume); 
 
		public abstract DownloadResult Download(string remFileName, string locFileName); 
 
		public abstract DownloadResult Download(string remFileName, string locFileName, bool resume); 
 
		public abstract DownloadResult Download(string remFileName, string locFileName, bool resume, long byteOffSet); 
 
		public abstract DownloadResult Download(string remFileName, string locFileName, bool resume, long byteOffSet, long byteStopDownload); 
 
		public abstract DownloadResult Download(string remFileName, string locFileName, bool resume, long byteOffSet, long byteStopDownload, long totalFileSize); 
 
		public abstract DownloadResult Download(string remFileName, string locFileName, bool resume, long byteOffSet, long byteStopDownload, long totalFileSize, bool isLastPart); 
 
		#region DownloadStarted Event 
		///  
		/// Download started event arguments 
		///  
		public class DownloadStartedEventArgs : EventArgs 
		{ 
			public DownloadStartedEventArgs () 
			{ 
			} 
		} 
		///  
		/// Delegate for Download Started Event 
		///  
		public delegate void DownloadStartedEventHandler(ProtocolClient sender, DownloadStartedEventArgs e); 
		///  
		/// The Download Started Event is raised when the download starts 
		///  
		public event DownloadStartedEventHandler DownloadStartedEvent; 
		///  
		/// OnDownloadStartedEvent 
		///  
		/// DownloadStartedEventArgs 
		protected virtual void OnDownloadStartedEvent(DownloadStartedEventArgs e) 
		{ 
			if (DownloadStartedEvent != null) 
			{ 
				DownloadStartedEvent(this, e); 
			} 
		} 
 
		#endregion 
 
		#region DataReceived Event 
		///  
		/// Data received event arguments 
		///  
		public class DataReceivedEventArgs : EventArgs 
		{ 
			private readonly long totalDataReceived; 
			///  
			/// Default constructor 
			///  
			/// Total amount of data in bytes received 
			public DataReceivedEventArgs (long totalData) 
			{ 
				this.totalDataReceived = totalData; 
			} 
			///  
			/// Read-only param to get the total number of bytes received 
			///  
			public long TotalDataReceived 
			{ 
				get 
				{ 
					return totalDataReceived; 
				} 
			} 
		} 
		///  
		/// Delegate for Data Received Event 
		///  
		public delegate void DataReceivedEventHandler(ProtocolClient sender, DataReceivedEventArgs e); 
		///  
		/// The Data Received Event is raised when data is received in the download module. 
		///  
		public event DataReceivedEventHandler DataReceivedEvent; 
		///  
		/// OnDataReceivedEvent 
		///  
		/// DataReceivedEventArgs 
		protected virtual void OnDataReceivedEvent(DataReceivedEventArgs e) 
		{ 
			if (DataReceivedEvent != null) 
			{ 
				DataReceivedEvent(this, e); 
			} 
		} 
		#endregion 
 
		#region DownloadStopped Event 
		///  
		/// Data received event arguments 
		///  
		public class DownloadStoppedEventArgs : EventArgs 
		{ 
			private readonly long totalDownloadStopped; 
			///  
			/// Default constructor 
			///  
			/// Total amount of data in bytes received 
			public DownloadStoppedEventArgs (long totalData) 
			{ 
				this.totalDownloadStopped = totalData; 
			} 
			///  
			/// Read-only param to get the total number of bytes received 
			///  
			public long TotalDownloadStopped 
			{ 
				get 
				{ 
					return totalDownloadStopped; 
				} 
			} 
		} 
		///  
		/// Delegate for Data Received Event 
		///  
		public delegate void DownloadStoppedEventHandler(ProtocolClient sender, DownloadStoppedEventArgs e); 
		///  
		/// The Data Received Event is raised when data is received in the download module. 
		///  
		public event DownloadStoppedEventHandler DownloadStoppedEvent; 
		///  
		/// OnDownloadStoppedEvent 
		///  
		/// DownloadStoppedEventArgs 
		protected virtual void OnDownloadStoppedEvent(DownloadStoppedEventArgs e) 
		{ 
			if (DownloadStoppedEvent != null) 
			{ 
				DownloadStoppedEvent(this, e); 
			} 
		} 
		#endregion 
 
		#region ResumeSupported Event 
		///  
		/// Resume supported event arguments 
		///  
		public class ResumeSupportedEventArgs : EventArgs 
		{ 
			private readonly bool isResumeSupported = false; 
			///  
			/// Default constructor 
			///  
			/// Is resume supported by the server 
			public ResumeSupportedEventArgs (bool resumeSupported) 
			{ 
				this.isResumeSupported = resumeSupported; 
			} 
			///  
			/// Read-only param to return whether resume is supported 
			///  
			public bool IsResumeSupported 
			{ 
				get 
				{ 
					return isResumeSupported; 
				} 
			} 
		} 
		///  
		/// Delegate for Resume Supported event 
		///  
		public delegate void ResumeSupportedEventHandler(ProtocolClient sender, ResumeSupportedEventArgs e); 
		///  
		/// The Resume Supported Event is raised when the connection discovers if resume is supported by the server 
		///  
		public event ResumeSupportedEventHandler ResumeSupportedEvent; 
		///  
		/// OnResumeSupportedEvent 
		///  
		/// ResumeSupportedEventArgs 
		protected virtual void OnResumeSupportedEvent(ResumeSupportedEventArgs e) 
		{ 
			if (ResumeSupportedEvent != null) 
			{ 
				ResumeSupportedEvent(this, e); 
			} 
		} 
		#endregion 
 
		#region Async methods 
 
		private delegate void LoginCallback(); 
		///  
		/// Asynchronous begin login method 
		///  
		///  
		///  
		public System.IAsyncResult BeginLogin(  System.AsyncCallback callback ) 
		{ 
			LoginCallback protocolCallback = new LoginCallback( this.Login); 
			return protocolCallback.BeginInvoke(callback, null); 
		} 
 
		private delegate void CloseCallback(); 
		///  
		/// Asynchronous begin close method 
		///  
		///  
		///  
		public System.IAsyncResult BeginClose(  System.AsyncCallback callback ) 
		{ 
			CloseCallback protocolCallback = new CloseCallback( this.Close); 
			return protocolCallback.BeginInvoke(callback, null); 
		} 
 
		private delegate Int64 GetFileSizeCallback(String fileName); 
		///  
		/// Asynchronous get filesize method 
		///  
		///  
		///  
		///  
		public System.IAsyncResult BeginGetFileSize( String fileName, System.AsyncCallback callback ) 
		{ 
			GetFileSizeCallback protocolCallback = new GetFileSizeCallback(this.GetFileSize); 
			return protocolCallback.BeginInvoke(fileName, callback, null); 
		} 
 
		protected delegate DownloadResult DownloadCallback(String remFileName); 
		///  
		/// Asynchronous begin download method 
		///  
		///  
		///  
		///  
		public System.IAsyncResult BeginDownload( String remFileName, System.AsyncCallback callback ) 
		{ 
			DownloadCallback protocolCallback = new DownloadCallback(this.Download); 
			return protocolCallback.BeginInvoke(remFileName, callback, null); 
		} 
 
		protected delegate DownloadResult DownloadFileNameResumeCallback(String remFileName,Boolean resume); 
		///  
		/// Asynchronous begin download method 
		///  
		///  
		///  
		///  
		///  
		public System.IAsyncResult BeginDownload( String remFileName,Boolean resume, System.AsyncCallback callback ) 
		{ 
			DownloadFileNameResumeCallback protocolCallback = new DownloadFileNameResumeCallback(this.Download); 
			return protocolCallback.BeginInvoke(remFileName, resume, callback, null); 
		} 
 
		protected delegate DownloadResult DownloadFileNameFileNameCallback(String remFileName,String locFileName); 
		///  
		/// Asynchronous begin download method 
		///  
		///  
		///  
		///  
		///  
		public System.IAsyncResult BeginDownload( String remFileName,String locFileName, System.AsyncCallback callback ) 
		{ 
			DownloadFileNameFileNameCallback protocolCallback = new DownloadFileNameFileNameCallback(this.Download); 
			return protocolCallback.BeginInvoke(remFileName, locFileName, callback, null); 
		} 
 
		protected delegate DownloadResult DownloadFileNameFileNameResumeCallback(String remFileName,String locFileName,Boolean resume); 
		///  
		/// Asynchronous begin download method 
		///  
		///  
		///  
		///  
		///  
		///  
		public System.IAsyncResult BeginDownload( String remFileName,String locFileName,Boolean resume, System.AsyncCallback callback ) 
		{ 
			DownloadFileNameFileNameResumeCallback protocolCallback = new DownloadFileNameFileNameResumeCallback(this.Download); 
			return protocolCallback.BeginInvoke(remFileName, locFileName, resume, callback, null); 
		} 
 
		protected delegate DownloadResult DownloadFileNameFileNameResumeOffsetStopAtCallback(string remFileName, string locFileName, Boolean resume, long byteOffset, long byteStopDownload); 
		///  
		/// Asynchronous begin download method 
		///  
		///  
		///  
		///  
		///  
		///  
		///  
		///  
		public System.IAsyncResult BeginDownload( String remFileName, String locFileName, Boolean resume, long byteOffset, long byteStopDownload, System.AsyncCallback callback ) 
		{ 
			DownloadFileNameFileNameResumeOffsetStopAtCallback protocolCallback = new DownloadFileNameFileNameResumeOffsetStopAtCallback(this.Download); 
			return protocolCallback.BeginInvoke(remFileName, locFileName, resume, byteOffset, byteStopDownload, callback, null); 
		} 
 
		protected delegate DownloadResult DownloadFileNameFileNameResumeOffsetStopAtFileSizeCallback(string remFileName, string locFileName, Boolean resume, long byteOffset, long byteStopDownload, long totalFileSize); 
		///  
		/// Asynchronous begin download method 
		///  
		///  
		///  
		///  
		///  
		///  
		///  
		///  
		///  
		public System.IAsyncResult BeginDownload( String remFileName, String locFileName, Boolean resume, long byteOffset, long byteStopDownload, long totalFileSize, System.AsyncCallback callback ) 
		{ 
			DownloadFileNameFileNameResumeOffsetStopAtFileSizeCallback protocolCallback = new DownloadFileNameFileNameResumeOffsetStopAtFileSizeCallback(this.Download); 
			return protocolCallback.BeginInvoke(remFileName, locFileName, resume, byteOffset, byteStopDownload, totalFileSize, callback, null); 
		} 
 
		public delegate DownloadResult DownloadFileNameFileNameResumeOffsetStopAtFileSizeLastPartCallback(string remFileName, string locFileName, Boolean resume, long byteOffset, long byteStopDownload, long totalFileSize, bool isLastPart); 
		///  
		/// Asynchronous begin download method 
		///  
		///  
		///  
		///  
		///  
		///  
		///  
		///  
		///  
		///  
		public System.IAsyncResult BeginDownload( String remFileName, String locFileName, Boolean resume, long byteOffset, long byteStopDownload, long totalFileSize, bool isLastPart, System.AsyncCallback callback ) 
		{ 
			DownloadFileNameFileNameResumeOffsetStopAtFileSizeLastPartCallback protocolCallback = new DownloadFileNameFileNameResumeOffsetStopAtFileSizeLastPartCallback(this.Download); 
			return protocolCallback.BeginInvoke(remFileName, locFileName, resume, byteOffset, byteStopDownload, totalFileSize, isLastPart, callback, null); 
		} 
 
		#endregion 
 
	} 
}