usingSystem;
usingSystem.Net;
usingSystem.IO;
usingSystem.Text;
usingSystem.Net.Sockets;
usingSystem.Diagnostics;
usingSystem.Runtime.Remoting;
usingSystem.Runtime.Remoting.Messaging;
/*
* FTP Client library in C#
* Author: Jaimon Mathew
* mailto:jaimonmathew@rediffmail.com
* http://www.csharphelp.com/archives/archive9.html
*
* Addapted for use by Dan Glass 07/03/03
*
* modify by twh 07/11/21
*/
namespacewhlib.net
{
publicclassFtpClient
{
publicclassFtpException:Exception
{
publicFtpException(stringmessage):base(message){}
publicFtpException(stringmessage,ExceptioninnerException):base(message,innerException){}
}
privatestaticintBUFFER_SIZE=512;
privatestaticEncodingASCII=Encoding.ASCII;
privateboolverboseDebugging=false;
// defaults
privatestringserver="localhost";
privatestringremotePath=".";
privatestringusername="anonymous";
privatestringpassword="anonymous@anonymous.net";
privatestringmessage=null;
privatestringresult=null;
privateintport=21;
privateintbytes=0;
privateintresultCode=0;
privateboolloggedin=false;
privateboolbinMode=false;
privateByte[]buffer=newByte[BUFFER_SIZE];
privateSocketclientSocket=null;
privateinttimeoutSeconds=10;
/// <summary>
/// Default contructor
/// </summary>
publicFtpClient()
{
}
/// <summary>
///
/// </summary>
/// <param name="server"></param>
/// <param name="username"></param>
/// <param name="password"></param>
publicFtpClient(stringserver,stringusername,stringpassword)
{
this.server=server;
this.username=username;
this.password=password;
}
/// <summary>
///
/// </summary>
/// <param name="server"></param>
/// <param name="username"></param>
/// <param name="password"></param>
/// <param name="timeoutSeconds"></param>
/// <param name="port"></param>
publicFtpClient(stringserver,stringusername,stringpassword,inttimeoutSeconds,intport)
{
this.server=server;
this.username=username;
this.password=password;
this.timeoutSeconds=timeoutSeconds;
this.port=port;
}
/// <summary>
/// Display all communications to the debug log
/// </summary>
publicboolVerboseDebugging
{
get
{
returnthis.verboseDebugging;
}
set
{
this.verboseDebugging=value;
}
}
/// <summary>
/// Remote server port. Typically TCP 21
/// </summary>
publicintPort
{
get
{
returnthis.port;
}
set
{
this.port=value;
}
}
/// <summary>
/// Timeout waiting for a response from server, in seconds.
/// </summary>
publicintTimeout
{
get
{
returnthis.timeoutSeconds;
}
set
{
this.timeoutSeconds=value;
}
}
/// <summary>
/// Gets and Sets the name of the FTP server.
/// </summary>
/// <returns></returns>
publicstringServer
{
get
{
returnthis.server;
}
set
{
this.server=value;
}
}
/// <summary>
/// Gets and Sets the port number.
/// </summary>
/// <returns></returns>
publicintRemotePort
{
get
{
returnthis.port;
}
set
{
this.port=value;
}
}
/// <summary>
/// GetS and Sets the remote directory.
/// </summary>
publicstringRemotePath
{
get
{
returnthis.remotePath;
}
set
{
this.remotePath=value;
}
}
/// <summary>
/// Gets and Sets the username.
/// </summary>
publicstringUsername
{
get
{
returnthis.username;
}
set
{
this.username=value;
}
}
/// <summary>
/// Gets and Set the password.
/// </summary>
publicstringPassword
{
get
{
returnthis.password;
}
set
{
this.password=value;
}
}
/// <summary>
/// If the value of mode is true, set binary mode for downloads, else, Ascii mode.
/// </summary>
publicboolBinaryMode
{
get
{
returnthis.binMode;
}
set
{
if(this.binMode==value)return;
if(value)
sendCommand("TYPE I");
else
sendCommand("TYPE A");
if(this.resultCode!=200)thrownewFtpException(result.Substring(4));
}
}
/// <summary>
/// Login to the remote server.
/// </summary>
publicvoidLogin()
{
if(this.loggedin)this.Close();
Debug.WriteLine("Opening connection to "+this.server,"FtpClient");
IPAddressaddr=null;
IPEndPointep=null;
try
{
this.clientSocket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
addr=Dns.Resolve(this.server).AddressList[0];
ep=newIPEndPoint(addr,this.port);
this.clientSocket.Connect(ep);
}
catch(Exceptionex)
{
// doubtfull
if(this.clientSocket!=null&&this.clientSocket.Connected)this.clientSocket.Close();
thrownewFtpException("Couldn't connect to remote server",ex);
}
this.readResponse();
if(this.resultCode!=220)
{
this.Close();
thrownewFtpException(this.result.Substring(4));
}
this.sendCommand("USER "+username);
if(!(this.resultCode==331||this.resultCode==230))
{
this.cleanup();
thrownewFtpException(this.result.Substring(4));
}
if(this.resultCode!=230)
{
this.sendCommand("PASS "+password);
if(!(this.resultCode==230||this.resultCode==202))
{
this.cleanup();
thrownewFtpException(this.result.Substring(4));
}
}
this.loggedin=true;
Debug.WriteLine("Connected to "+this.server,"FtpClient");
this.ChangeDir(this.remotePath);
}
/// <summary>
/// Close the FTP connection.
/// </summary>
publicvoidClose()
{
Debug.WriteLine("Closing connection to "+this.server,"FtpClient");
if(this.clientSocket!=null)
{
this.sendCommand("QUIT");
}
this.cleanup();
}
/// <summary>
/// Return a string array containing the remote directory's file list.
/// </summary>
/// <returns></returns>
publicstring[]GetFileList()
{
returnthis.GetFileList("*.*");
}
/// <summary>
/// Return a string array containing the remote directory's file list.
/// </summary>
/// <param name="mask"></param>
/// <returns></returns>
publicstring[]GetFileList(stringmask)
{
if(!this.loggedin)this.Login();
SocketcSocket=createDataSocket();
this.sendCommand("NLST "+mask);
if(!(this.resultCode==150||this.resultCode==125))thrownewFtpException(this.result.Substring(4));
this.message="";
DateTimetimeout=DateTime.Now.AddSeconds(this.timeoutSeconds);
while(timeout>DateTime.Now)
{
intbytes=cSocket.Receive(buffer,buffer.Length,0);
this.message+=ASCII.GetString(buffer,0,bytes);
if(bytes<this.buffer.Length)break;
}
string[]msg=this.message.Replace(""r","").Split('"n');
cSocket.Close();
if(this.message.IndexOf("No such file or directory")!=-1)
msg=newstring[]{};
this.readResponse();
if(this.resultCode!=226)
msg=newstring[]{};
// throw new FtpException(result.Substring(4));
returnmsg;
}
/// <summary>
/// GetFileList and return remotePath:modity by twh
/// </summary>
/// <param name="mask"></param>
/// <returns></returns>
publicstring[]GetFileList(stringmask,outstringremPath)
{
if(!this.loggedin)this.Login();
SocketcSocket=createDataSocket();
this.sendCommand("NLST "+mask);
if(!(this.resultCode==150||this.resultCode==125))thrownewFtpException(this.result.Substring(4));
this.message="";
DateTimetimeout=DateTime.Now.AddSeconds(this.timeoutSeconds);
while(timeout>DateTime.Now)
{
intbytes=cSocket.Receive(buffer,buffer.Length,0);
this.message+=ASCII.GetString(buffer,0,bytes);
if(bytes<this.buffer.Length)break;
}
string[]msg=this.message.Replace(""r","").Split('"n');
cSocket.Close();
if(this.message.IndexOf("No such file or directory")!=-1)
msg=newstring[]{};
this.readResponse();
if(this.resultCode!=226)
msg=newstring[]{};
// throw new FtpException(result.Substring(4));
this.sendCommand("PWD");
if(this.resultCode!=257)thrownewFtpException(result.Substring(4));
// gonna have to do better than this....
remPath=this.message.Split('"')[1];
returnmsg;
}
/// <summary>
/// Return the size of a file.
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
publiclongGetFileSize(stringfileName)
{
if(!this.loggedin)this.Login();
this.sendCommand("SIZE "+fileName);
longsize=0;
if(this.resultCode==213)
size=long.Parse(this.result.Substring(4));
else
thrownewFtpException(this.result.Substring(4));
returnsize;
}
/// <summary>
/// Download a file to the Assembly's local directory,
/// keeping the same file name.
/// </summary>
/// <param name="remFileName"></param>
publicvoidDownload(stringremFileName)
{
this.Download(remFileName,"",false);
}
/// <summary>
/// Download a remote file to the Assembly's local directory,
/// keeping the same file name, and set the resume flag.
/// </summary>
/// <param name="remFileName"></param>
/// <param name="resume"></param>
publicvoidDownload(stringremFileName,Booleanresume)
{
this.Download(remFileName,"",resume);
}
/// <summary>
/// Download a remote file to a local file name which can include
/// a path. The local file name will be created or overwritten,
/// but the path must exist.
/// </summary>
/// <param name="remFileName"></param>
/// <param name="locFileName"></param>
publicvoidDownload(stringremFileName,stringlocFileName)
{
this.Download(remFileName,locFileName,false);
}
/// <summary>
/// Download a remote file to a local file name which can include
/// a path, and set the resume flag. The local file name will be
/// created or overwritten, but the path must exist.
/// </summary>
/// <param name="remFileName"></param>
/// <param name="locFileName"></param>
/// <param name="resume"></param>
publicvoidDownload(stringremFileName,stringlocFileName,Booleanresume)
{
if(!this.loggedin)this.Login();
this.BinaryMode=true;
Debug.WriteLine("Downloading file "+remFileName+" from "+server+"/"+remotePath,"FtpClient");
if(locFileName.Equals(""))
{
locFileName=remFileName;
}
FileStreamoutput=null;
if(!File.Exists(locFileName))
output=File.Create(locFileName);
else
output=newFileStream(locFileName,FileMode.Open);
SocketcSocket=createDataSocket();
longoffset=0;
if(resume)
{
offset=output.Length;
if(offset>0)
{
this.sendCommand("REST "+offset);
if(this.resultCode!=350)
{
//Server dosnt support resuming
offset=0;
Debug.WriteLine("Resuming not supported:"+result.Substring(4),"FtpClient");
}
else
{
Debug.WriteLine("Resuming at offset "+offset,"FtpClient");
output.Seek(offset,SeekOrigin.Begin);
}
}
}
this.sendCommand("RETR "+remFileName);
if(this.resultCode!=150&&this.resultCode!=125)
{
thrownewFtpException(this.result.Substring(4));
}
DateTimetimeout=DateTime.Now.AddSeconds(this.timeoutSeconds);
while(timeout>DateTime.Now)
{
this.bytes=cSocket.Receive(buffer,buffer.Length,0);
output.Write(this.buffer,0,this.bytes);
if(this.bytes<=0)
{
break;
}
}
output.Close();
if(cSocket.Connected)cSocket.Close();
this.readResponse();
if(this.resultCode!=226&&this.resultCode!=250)
thrownewFtpException(this.result.Substring(4));
}
/// <summary>
/// Upload a file.
/// </summary>
/// <param name="fileName"></param>
publicvoidUpload(stringfileName)
{
this.Upload(fileName,false);
}
/// <summary>
/// Upload a file and set the resume flag.
/// </summary>
/// <param name="fileName"></param>
/// <param name="resume"></param>
publicvoidUpload(stringfileName,boolresume)
{
if(!this.loggedin)this.Login();
SocketcSocket=null;
longoffset=0;
if(resume)
{
try
{
this.BinaryMode=true;
offset=GetFileSize(Path.GetFileName(fileName));
}
catch(Exception)
{
// file not exist
offset=0;
}
}
// open stream to read file
FileStreaminput=newFileStream(fileName,FileMode.Open);
if(resume&&input.Length<offset)
{
// different file size
Debug.WriteLine("Overwriting "+fileName,"FtpClient");
offset=0;
}
elseif(resume&&input.Length==offset)
{
// file done
input.Close();
Debug.WriteLine("Skipping completed "+fileName+" - turn resume off to not detect.","FtpClient");
return;
}
// dont create untill we know that we need it
cSocket=this.createDataSocket();
if(offset>0)
{
this.sendCommand("REST "+offset);
if(this.resultCode!=350)
{
Debug.WriteLine("Resuming not supported","FtpClient");
offset=0;
}
}
this.sendCommand("STOR "+Path.GetFileName(fileName));
if(this.resultCode!=125&&this.resultCode!=150)thrownewFtpException(result.Substring(4));
if(offset!=0)
{
Debug.WriteLine("Resuming at offset "+offset,"FtpClient");
input.Seek(offset,SeekOrigin.Begin);
}
Debug.WriteLine("Uploading file "+fileName+" to "+remotePath,"FtpClient");
while((bytes=input.Read(buffer,0,buffer.Length))>0)
{
cSocket.Send(buffer,bytes,0);
}
input.Close();
if(cSocket.Connected)
{
cSocket.Close();
}
this.readResponse();
if(this.resultCode!=226&&this.resultCode!=250)thrownewFtpException(this.result.Substring(4));
}
/// <summary>
/// Upload a directory and its file contents
/// </summary>
/// <param name="path"></param>
/// <param name="recurse">Whether to recurse sub directories</param>
publicvoidUploadDirectory(stringpath,boolrecurse)
{
this.UploadDirectory(path,recurse,"*.*");
}
/// <summary>
/// Upload a directory and its file contents
/// </summary>
/// <param name="path"></param>
/// <param name="recurse">Whether to recurse sub directories</param>
/// <param name="mask">Only upload files of the given mask - everything is '*.*'</param>
publicvoidUploadDirectory(stringpath,boolrecurse,stringmask)
{
string[]dirs=path.Replace("/",@""").Split('""');
string rootDir = dirs[ dirs.Length - 1 ];
// make the root dir if it doed not exist
if ( this.GetFileList(rootDir).Length < 1 ) this.MakeDir(rootDir);
this.ChangeDir(rootDir);
foreach ( string file in Directory.GetFiles(path,mask) )
{
this.Upload(file,true);
}
if ( recurse )
{
foreach ( string directory in Directory.GetDirectories(path) )
{
this.UploadDirectory(directory,recurse,mask);
}
}
this.ChangeDir("..");
}
/// <summary>
/// Delete a file from the remote FTP server.
/// </summary>
/// <param name="fileName"></param>
publicvoidDeleteFile(stringfileName)
{
if(!this.loggedin)this.Login();
this.sendCommand("DELE "+fileName);
if(this.resultCode!=250)thrownewFtpException(this.result.Substring(4));
Debug.WriteLine("Deleted file "+fileName,"FtpClient");
}
/// <summary>
/// Rename a file on the remote FTP server.
/// </summary>
/// <param name="oldFileName"></param>
/// <param name="newFileName"></param>
/// <param name="overwrite">setting to false will throw exception if it exists</param>
publicvoidRenameFile(stringoldFileName,stringnewFileName,booloverwrite)
{
if(!this.loggedin)this.Login();
this.sendCommand("RNFR "+oldFileName);
if(this.resultCode!=350)thrownewFtpException(this.result.Substring(4));
if(!overwrite&&this.GetFileList(newFileName).Length>0)thrownewFtpException("File already exists");
this.sendCommand("RNTO "+newFileName);
if(this.resultCode!=250)thrownewFtpException(this.result.Substring(4));
Debug.WriteLine("Renamed file "+oldFileName+" to "+newFileName,"FtpClient");
}
/// <summary>
/// Create a directory on the remote FTP server.
/// </summary>
/// <param name="dirName"></param>
publicvoidMakeDir(stringdirName)
{
if(!this.loggedin)this.Login();
this.sendCommand("MKD "+dirName);
if(this.resultCode!=250&&this.resultCode!=257)thrownewFtpException(this.result.Substring(4));
Debug.WriteLine("Created directory "+dirName,"FtpClient");
}
/// <summary>
/// Delete a directory on the remote FTP server.
/// </summary>
/// <param name="dirName"></param>
publicvoidRemoveDir(stringdirName)
{
if(!this.loggedin)this.Login();
this.sendCommand("RMD "+dirName);
if(this.resultCode!=250)thrownewFtpException(this.result.Substring(4));
Debug.WriteLine("Removed directory "+dirName,"FtpClient");
}
/// <summary>
/// Change the current working directory on the remote FTP server.
/// </summary>
/// <param name="dirName"></param>
publicvoidChangeDir(stringdirName)
{
if(dirName==null||dirName.Equals(".")||dirName.Length==0)
{
return;
}
if(!this.loggedin)this.Login();
this.sendCommand("CWD "+dirName);
if(this.resultCode!=250)thrownewFtpException(result.Substring(4));
this.sendCommand("PWD");
if(this.resultCode!=257)thrownewFtpException(result.Substring(4));
// gonna have to do better than this....
this.remotePath=this.message.Split('"')[1];
Debug.WriteLine("Current directory is "+this.remotePath,"FtpClient");
}
/// <summary>
/// diy changedir
/// </summary>
/// <param name="dirName"></param>
///
/// <summary>
/// ChangeDir and retrun remote crrent Path :twh modify
/// </summary>
/// <param name="dirName"></param>
/// <param name="remPath"></param>
publicvoidChangeDir2(stringdirName,outstringremPath)
{
remPath="";
if(dirName==null||dirName.Equals(".")||dirName.Length==0)
{
return;
}
if(!this.loggedin)this.Login();
this.sendCommand("CWD "+dirName);
if(this.resultCode!=250)thrownewFtpException(result.Substring(4));
this.sendCommand("PWD");
if(this.resultCode!=257)thrownewFtpException(result.Substring(4));
// gonna have to do better than this....
this.remotePath=this.message.Split('"')[1];
Debug.WriteLine("Current directory is "+this.remotePath,"FtpClient");
remPath=remotePath;
}
/// <summary>
///
/// </summary>
privatevoidreadResponse()
{
this.message="";
this.result=this.readLine();
if(this.result.Length>3)
this.resultCode=int.Parse(this.result.Substring(0,3));
else
this.result=null;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
privatestringreadLine()
{
while(true)
{
this.bytes=clientSocket.Receive(this.buffer,this.buffer.Length,0);
this.message+=ASCII.GetString(this.buffer,0,this.bytes);
if(this.bytes<this.buffer.Length)
{
break;
}
}
string[]msg=this.message.Split('"n');
if(this.message.Length>2)
this.message=msg[msg.Length-2];
else
this.message=msg[0];
if(this.message.Length>4&&!this.message.Substring(3,1).Equals(" "))returnthis.readLine();
if(this.verboseDebugging)
{
for(inti=0;i<msg.Length-1;i++)
{
Debug.Write(msg[i],"FtpClient");
}
}
returnmessage;
}
/// <summary>
///
/// </summary>
/// <param name="command"></param>
privatevoidsendCommand(Stringcommand)
{
if(this.verboseDebugging)Debug.WriteLine(command,"FtpClient");
Byte[]cmdBytes=Encoding.ASCII.GetBytes((command+""r"n").ToCharArray());
clientSocket.Send(cmdBytes,cmdBytes.Length,0);
this.readResponse();
}
/// <summary>
/// when doing data transfers, we need to open another socket for it.
/// </summary>
/// <returns>Connected socket</returns>
privateSocketcreateDataSocket()
{
this.sendCommand("PASV");
if(this.resultCode!=227)thrownewFtpException(this.result.Substring(4));
intindex1=this.result.IndexOf('(');
intindex2=this.result.IndexOf(')');
stringipData=this.result.Substring(index1+1,index2-index1-1);
int[]parts=newint[6];
intlen=ipData.Length;
intpartCount=0;
stringbuf="";
for(inti=0;i<len&&partCount<=6;i++)
{
charch=char.Parse(ipData.Substring(i,1));
if(char.IsDigit(ch))
buf+=ch;
elseif(ch!=',')
thrownewFtpException("Malformed PASV result: "+result);
if(ch==','||i+1==len)
{
try
{
parts[partCount++]=int.Parse(buf);
buf="";
}
catch(Exceptionex)
{
thrownewFtpException("Malformed PASV result (not supported?): "+this.result,ex);
}
}
}
stringipAddress=parts[0]+"."+parts[1]+"."+parts[2]+"."+parts[3];
intport=(parts[4]<<8)+parts[5];
Socketsocket=null;
IPEndPointep=null;
try
{
socket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
ep=newIPEndPoint(Dns.Resolve(ipAddress).AddressList[0],port);
socket.Connect(ep);
}
catch(Exceptionex)
{
// doubtfull....
if(socket!=null&&socket.Connected)socket.Close();
thrownewFtpException("Can't connect to remote server",ex);
}
returnsocket;
}
/// <summary>
/// Always release those sockets.
/// </summary>
privatevoidcleanup()
{
if(this.clientSocket!=null)
{
this.clientSocket.Close();
this.clientSocket=null;
}
this.loggedin=false;
}
/// <summary>
/// Destuctor
/// </summary>
~FtpClient()
{
this.cleanup();
}
/**************************************************************************************************************/
#region Async methods (auto generated)
/*
WinInetApi.FtpClient ftp = new WinInetApi.FtpClient();
MethodInfo[] methods = ftp.GetType().GetMethods(BindingFlags.DeclaredOnly|BindingFlags.Instance|BindingFlags.Public);
foreach ( MethodInfo method in methods )
{
string param = "";
string values = "";
foreach ( ParameterInfo i in method.GetParameters() )
{
param += i.ParameterType.Name + " " + i.Name + ",";
values += i.Name + ",";
}
Debug.WriteLine("private delegate " + method.ReturnType.Name + " " + method.Name + "Callback(" + param.TrimEnd(',') + ");");
Debug.WriteLine("public System.IAsyncResult Begin" + method.Name + "( " + param + " System.AsyncCallback callback )");
Debug.WriteLine("{");
Debug.WriteLine("" + method.Name + "Callback ftpCallback = new " + method.Name + "Callback(" + values + " this." + method.Name + ");");
Debug.WriteLine("return ftpCallback.BeginInvoke(callback, null);");
Debug.WriteLine("}");
Debug.WriteLine("public void End" + method.Name + "(System.IAsyncResult asyncResult)");
Debug.WriteLine("{");
Debug.WriteLine(method.Name + "Callback fc = (" + method.Name + "Callback) ((AsyncResult)asyncResult).AsyncDelegate;");
Debug.WriteLine("fc.EndInvoke(asyncResult);");
Debug.WriteLine("}");
//Debug.WriteLine(method);
}
*/
privatedelegatevoidLoginCallback();
publicSystem.IAsyncResultBeginLogin( System.AsyncCallbackcallback)
{
LoginCallbackftpCallback=newLoginCallback(this.Login);
returnftpCallback.BeginInvoke(callback,null);
}
privatedelegatevoidCloseCallback();
publicSystem.IAsyncResultBeginClose( System.AsyncCallbackcallback)
{
CloseCallbackftpCallback=newCloseCallback(this.Close);
returnftpCallback.BeginInvoke(callback,null);
}
privatedelegateString[]GetFileListCallback();
publicSystem.IAsyncResultBeginGetFileList( System.AsyncCallbackcallback)
{
GetFileListCallbackftpCallback=newGetFileListCallback(this.GetFileList);
returnftpCallback.BeginInvoke(callback,null);
}
privatedelegateString[]GetFileListMaskCallback(Stringmask);
publicSystem.IAsyncResultBeginGetFileList(Stringmask,System.AsyncCallbackcallback)
{
GetFileListMaskCallbackftpCallback=newGetFileListMaskCallback(this.GetFileList);
returnftpCallback.BeginInvoke(mask,callback,null);
}
privatedelegateInt64GetFileSizeCallback(StringfileName);
publicSystem.IAsyncResultBeginGetFileSize(StringfileName,System.AsyncCallbackcallback)
{
GetFileSizeCallbackftpCallback=newGetFileSizeCallback(this.GetFileSize);
returnftpCallback.BeginInvoke(fileName,callback,null);
}
privatedelegatevoidDownloadCallback(StringremFileName);
publicSystem.IAsyncResultBeginDownload(StringremFileName,System.AsyncCallbackcallback)
{
DownloadCallbackftpCallback=newDownloadCallback(this.Download);
returnftpCallback.BeginInvoke(remFileName,callback,null);
}
privatedelegatevoidDownloadFileNameResumeCallback(StringremFileName,Booleanresume);
publicSystem.IAsyncResultBeginDownload(StringremFileName,Booleanresume,System.AsyncCallbackcallback)
{
DownloadFileNameResumeCallbackftpCallback=newDownloadFileNameResumeCallback(this.Download);
returnftpCallback.BeginInvoke(remFileName,resume,callback,null);
}
privatedelegatevoidDownloadFileNameFileNameCallback(StringremFileName,StringlocFileName);
publicSystem.IAsyncResultBeginDownload(StringremFileName,StringlocFileName,System.AsyncCallbackcallback)
{
DownloadFileNameFileNameCallbackftpCallback=newDownloadFileNameFileNameCallback(this.Download);
returnftpCallback.BeginInvoke(remFileName,locFileName,callback,null);
}
privatedelegatevoidDownloadFileNameFileNameResumeCallback(StringremFileName,StringlocFileName,Booleanresume);
publicSystem.IAsyncResultBeginDownload(StringremFileName,StringlocFileName,Booleanresume,System.AsyncCallbackcallback)
{
DownloadFileNameFileNameResumeCallbackftpCallback=newDownloadFileNameFileNameResumeCallback(this.Download);
returnftpCallback.BeginInvoke(remFileName,locFileName,resume,callback,null);
}
privatedelegatevoidUploadCallback(StringfileName);
publicSystem.IAsyncResultBeginUpload(StringfileName,System.AsyncCallbackcallback)
{
UploadCallbackftpCallback=newUploadCallback(this.Upload);
returnftpCallback.BeginInvoke(fileName,callback,null);
}
privatedelegatevoidUploadFileNameResumeCallback(StringfileName,Booleanresume);
publicSystem.IAsyncResultBeginUpload(StringfileName,Booleanresume,System.AsyncCallbackcallback)
{
UploadFileNameResumeCallbackftpCallback=newUploadFileNameResumeCallback(this.Upload);
returnftpCallback.BeginInvoke(fileName,resume,callback,null);
}
privatedelegatevoidUploadDirectoryCallback(Stringpath,Booleanrecurse);
publicSystem.IAsyncResultBeginUploadDirectory(Stringpath,Booleanrecurse,System.AsyncCallbackcallback)
{
UploadDirectoryCallbackftpCallback=newUploadDirectoryCallback(this.UploadDirectory);
returnftpCallback.BeginInvoke(path,recurse,callback,null);
}
privatedelegatevoidUploadDirectoryPathRecurseMaskCallback(Stringpath,Booleanrecurse,Stringmask);
publicSystem.IAsyncResultBeginUploadDirectory(Stringpath,Booleanrecurse,Stringmask,System.AsyncCallbackcallback)
{
UploadDirectoryPathRecurseMaskCallbackftpCallback=newUploadDirectoryPathRecurseMaskCallback(this.UploadDirectory);
returnftpCallback.BeginInvoke(path,recurse,mask,callback,null);
}
privatedelegatevoidDeleteFileCallback(StringfileName);
publicSystem.IAsyncResultBeginDeleteFile(StringfileName,System.AsyncCallbackcallback)
{
DeleteFileCallbackftpCallback=newDeleteFileCallback(this.DeleteFile);
returnftpCallback.BeginInvoke(fileName,callback,null);
}
privatedelegatevoidRenameFileCallback(StringoldFileName,StringnewFileName,Booleanoverwrite);
publicSystem.IAsyncResultBeginRenameFile(StringoldFileName,StringnewFileName,Booleanoverwrite,System.AsyncCallbackcallback)
{
RenameFileCallbackftpCallback=newRenameFileCallback(this.RenameFile);
returnftpCallback.BeginInvoke(oldFileName,newFileName,overwrite,callback,null);
}
privatedelegatevoidMakeDirCallback(StringdirName);
publicSystem.IAsyncResultBeginMakeDir(StringdirName,System.AsyncCallbackcallback)
{
MakeDirCallbackftpCallback=newMakeDirCallback(this.MakeDir);
returnftpCallback.BeginInvoke(dirName,callback,null);
}
privatedelegatevoidRemoveDirCallback(StringdirName);
publicSystem.IAsyncResultBeginRemoveDir(StringdirName,System.AsyncCallbackcallback)
{
RemoveDirCallbackftpCallback=newRemoveDirCallback(this.RemoveDir);
returnftpCallback.BeginInvoke(dirName,callback,null);
}
privatedelegatevoidChangeDirCallback(StringdirName);
publicSystem.IAsyncResultBeginChangeDir(StringdirName,System.AsyncCallbackcallback)
{
ChangeDirCallbackftpCallback=newChangeDirCallback(this.ChangeDir);
returnftpCallback.BeginInvoke(dirName,callback,null);
}
#endregion
}
}
usingSystem.Net;
usingSystem.IO;
usingSystem.Text;
usingSystem.Net.Sockets;
usingSystem.Diagnostics;
usingSystem.Runtime.Remoting;
usingSystem.Runtime.Remoting.Messaging;
/*
* FTP Client library in C#
* Author: Jaimon Mathew
* mailto:jaimonmathew@rediffmail.com
* http://www.csharphelp.com/archives/archive9.html
*
* Addapted for use by Dan Glass 07/03/03
*
* modify by twh 07/11/21
*/
namespacewhlib.net
{
publicclassFtpClient
{
publicclassFtpException:Exception
{
publicFtpException(stringmessage):base(message){}
publicFtpException(stringmessage,ExceptioninnerException):base(message,innerException){}
}
privatestaticintBUFFER_SIZE=512;
privatestaticEncodingASCII=Encoding.ASCII;
privateboolverboseDebugging=false;
// defaults
privatestringserver="localhost";
privatestringremotePath=".";
privatestringusername="anonymous";
privatestringpassword="anonymous@anonymous.net";
privatestringmessage=null;
privatestringresult=null;
privateintport=21;
privateintbytes=0;
privateintresultCode=0;
privateboolloggedin=false;
privateboolbinMode=false;
privateByte[]buffer=newByte[BUFFER_SIZE];
privateSocketclientSocket=null;
privateinttimeoutSeconds=10;
/// <summary>
/// Default contructor
/// </summary>
publicFtpClient()
{
}
/// <summary>
///
/// </summary>
/// <param name="server"></param>
/// <param name="username"></param>
/// <param name="password"></param>
publicFtpClient(stringserver,stringusername,stringpassword)
{
this.server=server;
this.username=username;
this.password=password;
}
/// <summary>
///
/// </summary>
/// <param name="server"></param>
/// <param name="username"></param>
/// <param name="password"></param>
/// <param name="timeoutSeconds"></param>
/// <param name="port"></param>
publicFtpClient(stringserver,stringusername,stringpassword,inttimeoutSeconds,intport)
{
this.server=server;
this.username=username;
this.password=password;
this.timeoutSeconds=timeoutSeconds;
this.port=port;
}
/// <summary>
/// Display all communications to the debug log
/// </summary>
publicboolVerboseDebugging
{
get
{
returnthis.verboseDebugging;
}
set
{
this.verboseDebugging=value;
}
}
/// <summary>
/// Remote server port. Typically TCP 21
/// </summary>
publicintPort
{
get
{
returnthis.port;
}
set
{
this.port=value;
}
}
/// <summary>
/// Timeout waiting for a response from server, in seconds.
/// </summary>
publicintTimeout
{
get
{
returnthis.timeoutSeconds;
}
set
{
this.timeoutSeconds=value;
}
}
/// <summary>
/// Gets and Sets the name of the FTP server.
/// </summary>
/// <returns></returns>
publicstringServer
{
get
{
returnthis.server;
}
set
{
this.server=value;
}
}
/// <summary>
/// Gets and Sets the port number.
/// </summary>
/// <returns></returns>
publicintRemotePort
{
get
{
returnthis.port;
}
set
{
this.port=value;
}
}
/// <summary>
/// GetS and Sets the remote directory.
/// </summary>
publicstringRemotePath
{
get
{
returnthis.remotePath;
}
set
{
this.remotePath=value;
}
}
/// <summary>
/// Gets and Sets the username.
/// </summary>
publicstringUsername
{
get
{
returnthis.username;
}
set
{
this.username=value;
}
}
/// <summary>
/// Gets and Set the password.
/// </summary>
publicstringPassword
{
get
{
returnthis.password;
}
set
{
this.password=value;
}
}
/// <summary>
/// If the value of mode is true, set binary mode for downloads, else, Ascii mode.
/// </summary>
publicboolBinaryMode
{
get
{
returnthis.binMode;
}
set
{
if(this.binMode==value)return;
if(value)
sendCommand("TYPE I");
else
sendCommand("TYPE A");
if(this.resultCode!=200)thrownewFtpException(result.Substring(4));
}
}
/// <summary>
/// Login to the remote server.
/// </summary>
publicvoidLogin()
{
if(this.loggedin)this.Close();
Debug.WriteLine("Opening connection to "+this.server,"FtpClient");
IPAddressaddr=null;
IPEndPointep=null;
try
{
this.clientSocket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
addr=Dns.Resolve(this.server).AddressList[0];
ep=newIPEndPoint(addr,this.port);
this.clientSocket.Connect(ep);
}
catch(Exceptionex)
{
// doubtfull
if(this.clientSocket!=null&&this.clientSocket.Connected)this.clientSocket.Close();
thrownewFtpException("Couldn't connect to remote server",ex);
}
this.readResponse();
if(this.resultCode!=220)
{
this.Close();
thrownewFtpException(this.result.Substring(4));
}
this.sendCommand("USER "+username);
if(!(this.resultCode==331||this.resultCode==230))
{
this.cleanup();
thrownewFtpException(this.result.Substring(4));
}
if(this.resultCode!=230)
{
this.sendCommand("PASS "+password);
if(!(this.resultCode==230||this.resultCode==202))
{
this.cleanup();
thrownewFtpException(this.result.Substring(4));
}
}
this.loggedin=true;
Debug.WriteLine("Connected to "+this.server,"FtpClient");
this.ChangeDir(this.remotePath);
}
/// <summary>
/// Close the FTP connection.
/// </summary>
publicvoidClose()
{
Debug.WriteLine("Closing connection to "+this.server,"FtpClient");
if(this.clientSocket!=null)
{
this.sendCommand("QUIT");
}
this.cleanup();
}
/// <summary>
/// Return a string array containing the remote directory's file list.
/// </summary>
/// <returns></returns>
publicstring[]GetFileList()
{
returnthis.GetFileList("*.*");
}
/// <summary>
/// Return a string array containing the remote directory's file list.
/// </summary>
/// <param name="mask"></param>
/// <returns></returns>
publicstring[]GetFileList(stringmask)
{
if(!this.loggedin)this.Login();
SocketcSocket=createDataSocket();
this.sendCommand("NLST "+mask);
if(!(this.resultCode==150||this.resultCode==125))thrownewFtpException(this.result.Substring(4));
this.message="";
DateTimetimeout=DateTime.Now.AddSeconds(this.timeoutSeconds);
while(timeout>DateTime.Now)
{
intbytes=cSocket.Receive(buffer,buffer.Length,0);
this.message+=ASCII.GetString(buffer,0,bytes);
if(bytes<this.buffer.Length)break;
}
string[]msg=this.message.Replace(""r","").Split('"n');
cSocket.Close();
if(this.message.IndexOf("No such file or directory")!=-1)
msg=newstring[]{};
this.readResponse();
if(this.resultCode!=226)
msg=newstring[]{};
// throw new FtpException(result.Substring(4));
returnmsg;
}
/// <summary>
/// GetFileList and return remotePath:modity by twh
/// </summary>
/// <param name="mask"></param>
/// <returns></returns>
publicstring[]GetFileList(stringmask,outstringremPath)
{
if(!this.loggedin)this.Login();
SocketcSocket=createDataSocket();
this.sendCommand("NLST "+mask);
if(!(this.resultCode==150||this.resultCode==125))thrownewFtpException(this.result.Substring(4));
this.message="";
DateTimetimeout=DateTime.Now.AddSeconds(this.timeoutSeconds);
while(timeout>DateTime.Now)
{
intbytes=cSocket.Receive(buffer,buffer.Length,0);
this.message+=ASCII.GetString(buffer,0,bytes);
if(bytes<this.buffer.Length)break;
}
string[]msg=this.message.Replace(""r","").Split('"n');
cSocket.Close();
if(this.message.IndexOf("No such file or directory")!=-1)
msg=newstring[]{};
this.readResponse();
if(this.resultCode!=226)
msg=newstring[]{};
// throw new FtpException(result.Substring(4));
this.sendCommand("PWD");
if(this.resultCode!=257)thrownewFtpException(result.Substring(4));
// gonna have to do better than this....
remPath=this.message.Split('"')[1];
returnmsg;
}
/// <summary>
/// Return the size of a file.
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
publiclongGetFileSize(stringfileName)
{
if(!this.loggedin)this.Login();
this.sendCommand("SIZE "+fileName);
longsize=0;
if(this.resultCode==213)
size=long.Parse(this.result.Substring(4));
else
thrownewFtpException(this.result.Substring(4));
returnsize;
}
/// <summary>
/// Download a file to the Assembly's local directory,
/// keeping the same file name.
/// </summary>
/// <param name="remFileName"></param>
publicvoidDownload(stringremFileName)
{
this.Download(remFileName,"",false);
}
/// <summary>
/// Download a remote file to the Assembly's local directory,
/// keeping the same file name, and set the resume flag.
/// </summary>
/// <param name="remFileName"></param>
/// <param name="resume"></param>
publicvoidDownload(stringremFileName,Booleanresume)
{
this.Download(remFileName,"",resume);
}
/// <summary>
/// Download a remote file to a local file name which can include
/// a path. The local file name will be created or overwritten,
/// but the path must exist.
/// </summary>
/// <param name="remFileName"></param>
/// <param name="locFileName"></param>
publicvoidDownload(stringremFileName,stringlocFileName)
{
this.Download(remFileName,locFileName,false);
}
/// <summary>
/// Download a remote file to a local file name which can include
/// a path, and set the resume flag. The local file name will be
/// created or overwritten, but the path must exist.
/// </summary>
/// <param name="remFileName"></param>
/// <param name="locFileName"></param>
/// <param name="resume"></param>
publicvoidDownload(stringremFileName,stringlocFileName,Booleanresume)
{
if(!this.loggedin)this.Login();
this.BinaryMode=true;
Debug.WriteLine("Downloading file "+remFileName+" from "+server+"/"+remotePath,"FtpClient");
if(locFileName.Equals(""))
{
locFileName=remFileName;
}
FileStreamoutput=null;
if(!File.Exists(locFileName))
output=File.Create(locFileName);
else
output=newFileStream(locFileName,FileMode.Open);
SocketcSocket=createDataSocket();
longoffset=0;
if(resume)
{
offset=output.Length;
if(offset>0)
{
this.sendCommand("REST "+offset);
if(this.resultCode!=350)
{
//Server dosnt support resuming
offset=0;
Debug.WriteLine("Resuming not supported:"+result.Substring(4),"FtpClient");
}
else
{
Debug.WriteLine("Resuming at offset "+offset,"FtpClient");
output.Seek(offset,SeekOrigin.Begin);
}
}
}
this.sendCommand("RETR "+remFileName);
if(this.resultCode!=150&&this.resultCode!=125)
{
thrownewFtpException(this.result.Substring(4));
}
DateTimetimeout=DateTime.Now.AddSeconds(this.timeoutSeconds);
while(timeout>DateTime.Now)
{
this.bytes=cSocket.Receive(buffer,buffer.Length,0);
output.Write(this.buffer,0,this.bytes);
if(this.bytes<=0)
{
break;
}
}
output.Close();
if(cSocket.Connected)cSocket.Close();
this.readResponse();
if(this.resultCode!=226&&this.resultCode!=250)
thrownewFtpException(this.result.Substring(4));
}
/// <summary>
/// Upload a file.
/// </summary>
/// <param name="fileName"></param>
publicvoidUpload(stringfileName)
{
this.Upload(fileName,false);
}
/// <summary>
/// Upload a file and set the resume flag.
/// </summary>
/// <param name="fileName"></param>
/// <param name="resume"></param>
publicvoidUpload(stringfileName,boolresume)
{
if(!this.loggedin)this.Login();
SocketcSocket=null;
longoffset=0;
if(resume)
{
try
{
this.BinaryMode=true;
offset=GetFileSize(Path.GetFileName(fileName));
}
catch(Exception)
{
// file not exist
offset=0;
}
}
// open stream to read file
FileStreaminput=newFileStream(fileName,FileMode.Open);
if(resume&&input.Length<offset)
{
// different file size
Debug.WriteLine("Overwriting "+fileName,"FtpClient");
offset=0;
}
elseif(resume&&input.Length==offset)
{
// file done
input.Close();
Debug.WriteLine("Skipping completed "+fileName+" - turn resume off to not detect.","FtpClient");
return;
}
// dont create untill we know that we need it
cSocket=this.createDataSocket();
if(offset>0)
{
this.sendCommand("REST "+offset);
if(this.resultCode!=350)
{
Debug.WriteLine("Resuming not supported","FtpClient");
offset=0;
}
}
this.sendCommand("STOR "+Path.GetFileName(fileName));
if(this.resultCode!=125&&this.resultCode!=150)thrownewFtpException(result.Substring(4));
if(offset!=0)
{
Debug.WriteLine("Resuming at offset "+offset,"FtpClient");
input.Seek(offset,SeekOrigin.Begin);
}
Debug.WriteLine("Uploading file "+fileName+" to "+remotePath,"FtpClient");
while((bytes=input.Read(buffer,0,buffer.Length))>0)
{
cSocket.Send(buffer,bytes,0);
}
input.Close();
if(cSocket.Connected)
{
cSocket.Close();
}
this.readResponse();
if(this.resultCode!=226&&this.resultCode!=250)thrownewFtpException(this.result.Substring(4));
}
/// <summary>
/// Upload a directory and its file contents
/// </summary>
/// <param name="path"></param>
/// <param name="recurse">Whether to recurse sub directories</param>
publicvoidUploadDirectory(stringpath,boolrecurse)
{
this.UploadDirectory(path,recurse,"*.*");
}
/// <summary>
/// Upload a directory and its file contents
/// </summary>
/// <param name="path"></param>
/// <param name="recurse">Whether to recurse sub directories</param>
/// <param name="mask">Only upload files of the given mask - everything is '*.*'</param>
publicvoidUploadDirectory(stringpath,boolrecurse,stringmask)
{
string[]dirs=path.Replace("/",@""").Split('""');
string rootDir = dirs[ dirs.Length - 1 ];
// make the root dir if it doed not exist
if ( this.GetFileList(rootDir).Length < 1 ) this.MakeDir(rootDir);
this.ChangeDir(rootDir);
foreach ( string file in Directory.GetFiles(path,mask) )
{
this.Upload(file,true);
}
if ( recurse )
{
foreach ( string directory in Directory.GetDirectories(path) )
{
this.UploadDirectory(directory,recurse,mask);
}
}
this.ChangeDir("..");
}
/// <summary>
/// Delete a file from the remote FTP server.
/// </summary>
/// <param name="fileName"></param>
publicvoidDeleteFile(stringfileName)
{
if(!this.loggedin)this.Login();
this.sendCommand("DELE "+fileName);
if(this.resultCode!=250)thrownewFtpException(this.result.Substring(4));
Debug.WriteLine("Deleted file "+fileName,"FtpClient");
}
/// <summary>
/// Rename a file on the remote FTP server.
/// </summary>
/// <param name="oldFileName"></param>
/// <param name="newFileName"></param>
/// <param name="overwrite">setting to false will throw exception if it exists</param>
publicvoidRenameFile(stringoldFileName,stringnewFileName,booloverwrite)
{
if(!this.loggedin)this.Login();
this.sendCommand("RNFR "+oldFileName);
if(this.resultCode!=350)thrownewFtpException(this.result.Substring(4));
if(!overwrite&&this.GetFileList(newFileName).Length>0)thrownewFtpException("File already exists");
this.sendCommand("RNTO "+newFileName);
if(this.resultCode!=250)thrownewFtpException(this.result.Substring(4));
Debug.WriteLine("Renamed file "+oldFileName+" to "+newFileName,"FtpClient");
}
/// <summary>
/// Create a directory on the remote FTP server.
/// </summary>
/// <param name="dirName"></param>
publicvoidMakeDir(stringdirName)
{
if(!this.loggedin)this.Login();
this.sendCommand("MKD "+dirName);
if(this.resultCode!=250&&this.resultCode!=257)thrownewFtpException(this.result.Substring(4));
Debug.WriteLine("Created directory "+dirName,"FtpClient");
}
/// <summary>
/// Delete a directory on the remote FTP server.
/// </summary>
/// <param name="dirName"></param>
publicvoidRemoveDir(stringdirName)
{
if(!this.loggedin)this.Login();
this.sendCommand("RMD "+dirName);
if(this.resultCode!=250)thrownewFtpException(this.result.Substring(4));
Debug.WriteLine("Removed directory "+dirName,"FtpClient");
}
/// <summary>
/// Change the current working directory on the remote FTP server.
/// </summary>
/// <param name="dirName"></param>
publicvoidChangeDir(stringdirName)
{
if(dirName==null||dirName.Equals(".")||dirName.Length==0)
{
return;
}
if(!this.loggedin)this.Login();
this.sendCommand("CWD "+dirName);
if(this.resultCode!=250)thrownewFtpException(result.Substring(4));
this.sendCommand("PWD");
if(this.resultCode!=257)thrownewFtpException(result.Substring(4));
// gonna have to do better than this....
this.remotePath=this.message.Split('"')[1];
Debug.WriteLine("Current directory is "+this.remotePath,"FtpClient");
}
/// <summary>
/// diy changedir
/// </summary>
/// <param name="dirName"></param>
///
/// <summary>
/// ChangeDir and retrun remote crrent Path :twh modify
/// </summary>
/// <param name="dirName"></param>
/// <param name="remPath"></param>
publicvoidChangeDir2(stringdirName,outstringremPath)
{
remPath="";
if(dirName==null||dirName.Equals(".")||dirName.Length==0)
{
return;
}
if(!this.loggedin)this.Login();
this.sendCommand("CWD "+dirName);
if(this.resultCode!=250)thrownewFtpException(result.Substring(4));
this.sendCommand("PWD");
if(this.resultCode!=257)thrownewFtpException(result.Substring(4));
// gonna have to do better than this....
this.remotePath=this.message.Split('"')[1];
Debug.WriteLine("Current directory is "+this.remotePath,"FtpClient");
remPath=remotePath;
}
/// <summary>
///
/// </summary>
privatevoidreadResponse()
{
this.message="";
this.result=this.readLine();
if(this.result.Length>3)
this.resultCode=int.Parse(this.result.Substring(0,3));
else
this.result=null;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
privatestringreadLine()
{
while(true)
{
this.bytes=clientSocket.Receive(this.buffer,this.buffer.Length,0);
this.message+=ASCII.GetString(this.buffer,0,this.bytes);
if(this.bytes<this.buffer.Length)
{
break;
}
}
string[]msg=this.message.Split('"n');
if(this.message.Length>2)
this.message=msg[msg.Length-2];
else
this.message=msg[0];
if(this.message.Length>4&&!this.message.Substring(3,1).Equals(" "))returnthis.readLine();
if(this.verboseDebugging)
{
for(inti=0;i<msg.Length-1;i++)
{
Debug.Write(msg[i],"FtpClient");
}
}
returnmessage;
}
/// <summary>
///
/// </summary>
/// <param name="command"></param>
privatevoidsendCommand(Stringcommand)
{
if(this.verboseDebugging)Debug.WriteLine(command,"FtpClient");
Byte[]cmdBytes=Encoding.ASCII.GetBytes((command+""r"n").ToCharArray());
clientSocket.Send(cmdBytes,cmdBytes.Length,0);
this.readResponse();
}
/// <summary>
/// when doing data transfers, we need to open another socket for it.
/// </summary>
/// <returns>Connected socket</returns>
privateSocketcreateDataSocket()
{
this.sendCommand("PASV");
if(this.resultCode!=227)thrownewFtpException(this.result.Substring(4));
intindex1=this.result.IndexOf('(');
intindex2=this.result.IndexOf(')');
stringipData=this.result.Substring(index1+1,index2-index1-1);
int[]parts=newint[6];
intlen=ipData.Length;
intpartCount=0;
stringbuf="";
for(inti=0;i<len&&partCount<=6;i++)
{
charch=char.Parse(ipData.Substring(i,1));
if(char.IsDigit(ch))
buf+=ch;
elseif(ch!=',')
thrownewFtpException("Malformed PASV result: "+result);
if(ch==','||i+1==len)
{
try
{
parts[partCount++]=int.Parse(buf);
buf="";
}
catch(Exceptionex)
{
thrownewFtpException("Malformed PASV result (not supported?): "+this.result,ex);
}
}
}
stringipAddress=parts[0]+"."+parts[1]+"."+parts[2]+"."+parts[3];
intport=(parts[4]<<8)+parts[5];
Socketsocket=null;
IPEndPointep=null;
try
{
socket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
ep=newIPEndPoint(Dns.Resolve(ipAddress).AddressList[0],port);
socket.Connect(ep);
}
catch(Exceptionex)
{
// doubtfull....
if(socket!=null&&socket.Connected)socket.Close();
thrownewFtpException("Can't connect to remote server",ex);
}
returnsocket;
}
/// <summary>
/// Always release those sockets.
/// </summary>
privatevoidcleanup()
{
if(this.clientSocket!=null)
{
this.clientSocket.Close();
this.clientSocket=null;
}
this.loggedin=false;
}
/// <summary>
/// Destuctor
/// </summary>
~FtpClient()
{
this.cleanup();
}
/**************************************************************************************************************/
#region Async methods (auto generated)
/*
WinInetApi.FtpClient ftp = new WinInetApi.FtpClient();
MethodInfo[] methods = ftp.GetType().GetMethods(BindingFlags.DeclaredOnly|BindingFlags.Instance|BindingFlags.Public);
foreach ( MethodInfo method in methods )
{
string param = "";
string values = "";
foreach ( ParameterInfo i in method.GetParameters() )
{
param += i.ParameterType.Name + " " + i.Name + ",";
values += i.Name + ",";
}
Debug.WriteLine("private delegate " + method.ReturnType.Name + " " + method.Name + "Callback(" + param.TrimEnd(',') + ");");
Debug.WriteLine("public System.IAsyncResult Begin" + method.Name + "( " + param + " System.AsyncCallback callback )");
Debug.WriteLine("{");
Debug.WriteLine("" + method.Name + "Callback ftpCallback = new " + method.Name + "Callback(" + values + " this." + method.Name + ");");
Debug.WriteLine("return ftpCallback.BeginInvoke(callback, null);");
Debug.WriteLine("}");
Debug.WriteLine("public void End" + method.Name + "(System.IAsyncResult asyncResult)");
Debug.WriteLine("{");
Debug.WriteLine(method.Name + "Callback fc = (" + method.Name + "Callback) ((AsyncResult)asyncResult).AsyncDelegate;");
Debug.WriteLine("fc.EndInvoke(asyncResult);");
Debug.WriteLine("}");
//Debug.WriteLine(method);
}
*/
privatedelegatevoidLoginCallback();
publicSystem.IAsyncResultBeginLogin( System.AsyncCallbackcallback)
{
LoginCallbackftpCallback=newLoginCallback(this.Login);
returnftpCallback.BeginInvoke(callback,null);
}
privatedelegatevoidCloseCallback();
publicSystem.IAsyncResultBeginClose( System.AsyncCallbackcallback)
{
CloseCallbackftpCallback=newCloseCallback(this.Close);
returnftpCallback.BeginInvoke(callback,null);
}
privatedelegateString[]GetFileListCallback();
publicSystem.IAsyncResultBeginGetFileList( System.AsyncCallbackcallback)
{
GetFileListCallbackftpCallback=newGetFileListCallback(this.GetFileList);
returnftpCallback.BeginInvoke(callback,null);
}
privatedelegateString[]GetFileListMaskCallback(Stringmask);
publicSystem.IAsyncResultBeginGetFileList(Stringmask,System.AsyncCallbackcallback)
{
GetFileListMaskCallbackftpCallback=newGetFileListMaskCallback(this.GetFileList);
returnftpCallback.BeginInvoke(mask,callback,null);
}
privatedelegateInt64GetFileSizeCallback(StringfileName);
publicSystem.IAsyncResultBeginGetFileSize(StringfileName,System.AsyncCallbackcallback)
{
GetFileSizeCallbackftpCallback=newGetFileSizeCallback(this.GetFileSize);
returnftpCallback.BeginInvoke(fileName,callback,null);
}
privatedelegatevoidDownloadCallback(StringremFileName);
publicSystem.IAsyncResultBeginDownload(StringremFileName,System.AsyncCallbackcallback)
{
DownloadCallbackftpCallback=newDownloadCallback(this.Download);
returnftpCallback.BeginInvoke(remFileName,callback,null);
}
privatedelegatevoidDownloadFileNameResumeCallback(StringremFileName,Booleanresume);
publicSystem.IAsyncResultBeginDownload(StringremFileName,Booleanresume,System.AsyncCallbackcallback)
{
DownloadFileNameResumeCallbackftpCallback=newDownloadFileNameResumeCallback(this.Download);
returnftpCallback.BeginInvoke(remFileName,resume,callback,null);
}
privatedelegatevoidDownloadFileNameFileNameCallback(StringremFileName,StringlocFileName);
publicSystem.IAsyncResultBeginDownload(StringremFileName,StringlocFileName,System.AsyncCallbackcallback)
{
DownloadFileNameFileNameCallbackftpCallback=newDownloadFileNameFileNameCallback(this.Download);
returnftpCallback.BeginInvoke(remFileName,locFileName,callback,null);
}
privatedelegatevoidDownloadFileNameFileNameResumeCallback(StringremFileName,StringlocFileName,Booleanresume);
publicSystem.IAsyncResultBeginDownload(StringremFileName,StringlocFileName,Booleanresume,System.AsyncCallbackcallback)
{
DownloadFileNameFileNameResumeCallbackftpCallback=newDownloadFileNameFileNameResumeCallback(this.Download);
returnftpCallback.BeginInvoke(remFileName,locFileName,resume,callback,null);
}
privatedelegatevoidUploadCallback(StringfileName);
publicSystem.IAsyncResultBeginUpload(StringfileName,System.AsyncCallbackcallback)
{
UploadCallbackftpCallback=newUploadCallback(this.Upload);
returnftpCallback.BeginInvoke(fileName,callback,null);
}
privatedelegatevoidUploadFileNameResumeCallback(StringfileName,Booleanresume);
publicSystem.IAsyncResultBeginUpload(StringfileName,Booleanresume,System.AsyncCallbackcallback)
{
UploadFileNameResumeCallbackftpCallback=newUploadFileNameResumeCallback(this.Upload);
returnftpCallback.BeginInvoke(fileName,resume,callback,null);
}
privatedelegatevoidUploadDirectoryCallback(Stringpath,Booleanrecurse);
publicSystem.IAsyncResultBeginUploadDirectory(Stringpath,Booleanrecurse,System.AsyncCallbackcallback)
{
UploadDirectoryCallbackftpCallback=newUploadDirectoryCallback(this.UploadDirectory);
returnftpCallback.BeginInvoke(path,recurse,callback,null);
}
privatedelegatevoidUploadDirectoryPathRecurseMaskCallback(Stringpath,Booleanrecurse,Stringmask);
publicSystem.IAsyncResultBeginUploadDirectory(Stringpath,Booleanrecurse,Stringmask,System.AsyncCallbackcallback)
{
UploadDirectoryPathRecurseMaskCallbackftpCallback=newUploadDirectoryPathRecurseMaskCallback(this.UploadDirectory);
returnftpCallback.BeginInvoke(path,recurse,mask,callback,null);
}
privatedelegatevoidDeleteFileCallback(StringfileName);
publicSystem.IAsyncResultBeginDeleteFile(StringfileName,System.AsyncCallbackcallback)
{
DeleteFileCallbackftpCallback=newDeleteFileCallback(this.DeleteFile);
returnftpCallback.BeginInvoke(fileName,callback,null);
}
privatedelegatevoidRenameFileCallback(StringoldFileName,StringnewFileName,Booleanoverwrite);
publicSystem.IAsyncResultBeginRenameFile(StringoldFileName,StringnewFileName,Booleanoverwrite,System.AsyncCallbackcallback)
{
RenameFileCallbackftpCallback=newRenameFileCallback(this.RenameFile);
returnftpCallback.BeginInvoke(oldFileName,newFileName,overwrite,callback,null);
}
privatedelegatevoidMakeDirCallback(StringdirName);
publicSystem.IAsyncResultBeginMakeDir(StringdirName,System.AsyncCallbackcallback)
{
MakeDirCallbackftpCallback=newMakeDirCallback(this.MakeDir);
returnftpCallback.BeginInvoke(dirName,callback,null);
}
privatedelegatevoidRemoveDirCallback(StringdirName);
publicSystem.IAsyncResultBeginRemoveDir(StringdirName,System.AsyncCallbackcallback)
{
RemoveDirCallbackftpCallback=newRemoveDirCallback(this.RemoveDir);
returnftpCallback.BeginInvoke(dirName,callback,null);
}
privatedelegatevoidChangeDirCallback(StringdirName);
publicSystem.IAsyncResultBeginChangeDir(StringdirName,System.AsyncCallbackcallback)
{
ChangeDirCallbackftpCallback=newChangeDirCallback(this.ChangeDir);
returnftpCallback.BeginInvoke(dirName,callback,null);
}
#endregion
}
}