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
}
}