Click here to Skip to main content
15,886,362 members
Articles / Programming Languages / C#
Article

FTP client library for C#

Rate me:
Please Sign up or sign in to vote.
4.77/5 (88 votes)
27 Mar 20031 min read 571.2K   14.5K   217   110
FTP client library for C#, including asynchronous operations.

Overview

Finding a fully working, lightweight FTP client, that had no GUI, was free, and came with source code, was difficult. This API is based on a work, Jaimon Mathew had done, and I have added some methods, cleaned up the code, debugged it and added some error handling, logging, debugging etc.

It is easy to use. Here is a code example:

C#
FtpClient ftp = new FtpClient(FtpServer,FtpUserName,FtpPassword);
ftp.Login();
ftp.Upload(@"C:\image.jpg");
ftp.Close();

Not so difficult now, is it? I am using it in my WebCamService list on this site, so if you want to see it in action, go here.

I started out wrapping fully the WinInet API, but it was such a labourous task that it made sense just to do the FTP. Since Microsoft has great support for HTTP, I could skip that, and later work on SMTP.

Features

  • Upload
  • Recursive upload
  • Download
  • Resume
  • Delete
  • Rename
  • Create directory
  • Asynchronous operation

Shortcomings

  • Not fully tested
  • No real error handling
  • No download recourse yet
  • Rename will overwrite, if the target already exists

Asynchronous operation

A little more advanced, the asynchronous operation is used when you need the job, to fork while your code continues over the method. All asynchronous methods start with Begin.

Using it is simple. You need a couple of things, an AsyncCallback object and a method which it handles.

C#
private FtpClient ftp = null;

private void UploadPicture(string imagePath)
{
    string FtpServer = ConfigurationSettings.AppSettings["FtpServer"];
    string FtpUserName = ConfigurationSettings.AppSettings["FtpUserName"];
    string FtpPassword = ConfigurationSettings.AppSettings["FtpPassword"];

    AsyncCallback callback = new AsyncCallback(CloseConnection);

    ftp = new FtpClient(FtpServer,FtpUserName,FtpPassword);
    ftp.Login();
    ftp.BeginUpload(imagePath, callback);
    ftp.Close();
}

private void CloseConnection(IAsyncResult result)
{
    Debug.WriteLine(result.IsCompleted.ToString());

    if ( ftp != null ) ftp.Close();
        ftp = null;
} 

When the upload finishes or throws an exception, the CloseConnection method will be called.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Architect support.com
Australia Australia

Comments and Discussions

 
GeneralAnother free, open-source .NET FTP component Pin
h_c_a_andersen11-Nov-04 11:45
h_c_a_andersen11-Nov-04 11:45 
QuestionHave any body here actualy looked at the code? Pin
Arnt1-Nov-04 12:31
Arnt1-Nov-04 12:31 
GeneralNot working Pin
agolovan29-Sep-04 14:50
agolovan29-Sep-04 14:50 
GeneralRe: Not working Pin
mohit bhat18-Nov-04 3:22
mohit bhat18-Nov-04 3:22 
GeneralRe: Not working Pin
Anonymous24-Jan-05 19:06
Anonymous24-Jan-05 19:06 
GeneralIt doesn't work with the IIS FTP server if a welcome message is set Pin
Justin Couto9-Jun-04 6:15
Justin Couto9-Jun-04 6:15 
GeneralRe: It doesn't work with the IIS FTP server if a welcome message is set Pin
Jose Lopes da Cruz25-Aug-04 5:34
Jose Lopes da Cruz25-Aug-04 5:34 
GeneralRe: It doesn't work with the IIS FTP server if a welcome message is set Pin
GoToSleep22-Sep-05 5:41
GoToSleep22-Sep-05 5:41 
I also ran into this problem. The reason that the original code did not work correctly was probably because it did not handle multi-line messages correctly. My welcome message is returned as "230-Hello, Good People...". The dash indicates a multipe part message. See below FTP RFC 959...

The original Jaimon Mathew code modified as below seem to resolve the multi-line problem as well.

//<br />
// Done when 3 digits followed by space<br />
//<br />
private bool isDone( byte []b, long read )<br />
{<br />
	if ( read >= 4 <br />
		 && Char.IsDigit((char)b[0]) <br />
		 && Char.IsDigit((char)b[1])<br />
		 && Char.IsDigit((char)b[2])<br />
		 && Char.IsWhiteSpace((char)b[3])<br />
	   )<br />
	{<br />
		return true;<br />
	}<br />
<br />
	return false;<br />
}<br />
private string readLine()<br />
{<br />
<br />
	while (true)<br />
	{<br />
		bytes = clientSocket.Receive(buffer, buffer.Length, 0);<br />
		mes += ASCII.GetString(buffer, 0, bytes);<br />
		if (bytes < buffer.Length && isDone(buffer,bytes) )<br />
		{<br />
			break;<br />
		}<br />
	}<br />
<br />
	char[] seperator = {'\n'};<br />
	string[] mess = mes.Split(seperator);<br />
<br />
	if (mes.Length > 2)<br />
	{<br />
		mes = mess[mess.Length-2];<br />
	} else<br />
	{<br />
		mes = mess[0];<br />
	}<br />
<br />
	if (mes.Length < 4)<br />
	{<br />
		mes += "    Corrupt reply from ftp server, (Length < 4)";<br />
	}<br />
<br />
	if (debug)<br />
	{<br />
		for (int k=0;k < mess.Length-1;k++)<br />
		{<br />
			Trace.WriteLine(mess[k]);<br />
		}<br />
	}<br />
	return mes;<br />
}<br />


Below is a quote from http://www.faqs.org/rfcs/rfc959.html[^]

"Thus the format for multi-line replies is that the first line will begin with the exact required reply code, followed immediately by a Hyphen, "-" (also known as Minus), followed by text. The last line will begin with the same code, followed immediately by Space <sp>, optionally some text, and the Telnet end-of-line code.


For example:
123-First line
Second line
234 A line beginning with numbers
123 The last line

The user-process then simply needs to search for the second occurrence of the same reply code, followed by <sp> (Space), at the beginning of a line, and ignore all intermediary lines. If an intermediary line begins with a 3-digit number, the Server must pad the front to avoid confusion."


-- modified at 13:31 Thursday 22nd September, 2005
QuestionNo File Uploading??? Pin
_stormbringer_20-May-04 10:15
_stormbringer_20-May-04 10:15 
Generalasync Pin
toni113-May-04 4:13
toni113-May-04 4:13 
GeneralBetter version. Pin
Dan Glass10-May-04 11:55
Dan Glass10-May-04 11:55 
GeneralRe: Better version. Pin
Anonymous11-May-04 5:32
Anonymous11-May-04 5:32 
GeneralRe: Better version. Pin
Anonymous11-May-04 6:14
Anonymous11-May-04 6:14 
GeneralRe: Better version. Pin
Anonymous11-Oct-04 22:11
Anonymous11-Oct-04 22:11 
GeneralI keep getting 530 Login or Password incorrect Pin
Anonymous10-May-04 11:46
Anonymous10-May-04 11:46 
GeneralThanks a ton. Pin
supertedusa21-Apr-04 8:59
supertedusa21-Apr-04 8:59 
GeneralTwo Thumbs Up Pin
Gitaraman21-Mar-04 19:15
Gitaraman21-Mar-04 19:15 
GeneralAsync feature is smoke and mirrors Pin
Ed Brey6-Mar-04 11:18
Ed Brey6-Mar-04 11:18 
GeneralChange file permissions Pin
hemko124-Feb-04 4:14
hemko124-Feb-04 4:14 
GeneralRe: Change file permissions Pin
Andrlage3-May-07 12:57
Andrlage3-May-07 12:57 
GeneralSwitch passive mode! Pin
Marc Schneider9-Feb-04 6:21
Marc Schneider9-Feb-04 6:21 
GeneralShould implement IDisposable Pin
Ed Brey3-Feb-04 0:08
Ed Brey3-Feb-04 0:08 
GeneralGr8 one.... but two big bugs Pin
mad050311-Jan-04 16:34
mad050311-Jan-04 16:34 
GeneralRe: Gr8 one.... but two big bugs Pin
dtelford7-Apr-04 11:40
dtelford7-Apr-04 11:40 
GeneralWorks fine for me ! Pin
lurkbat9-Jan-04 2:10
lurkbat9-Jan-04 2:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.