A C# FTP Server

Introduction

This is a fully functional FTP server that works with Internet Explorer and Netscape. I think the code itself is self explanatory. Eveything starts with a main form (MainForm.cs). Each user's starting directories are set up in UserForm.cs. There are some points of note:

Point 1: Adding Users

You must add users first, before using the FTP server.

The buttons in the user's dialog operate only if a user is selected.

Point 2: Functionality

This server will work with most clients, including Internet Explorer and Netscape Navigator. Each use a different method of transferring data (see below for a link to the FTP specification that gives more information).

Point 3: The FTP Server Is in an Assembly

Now, why do this? Surely you won't ever want to use an FTP server elsewhere? Nope! In actual fact, I've come across several usages of the FTP protocol other than just file transfer. Which brings me to Point 4...

Point 4: The Interface to the File System Is Replaceable

All file system accesses (for example, file open/write, list directory files, and so forth) go through a set of interfaces (see Assembly.Ftp.FileSystem.IFile, and so on).

The class factory for the file system object—the object that creates the file system object (Assembly.Ftp.FileSystem.IFileSystemClassFactory)—is passed in to the FTP server on creation. You can replace this with whatever you want (derived from IFileSystemClassFactory) and create classes that derive from IFileSystem, IFile, and IFileInfo to get the FTP server to do what you want.

Now, why do this? Well, this gives a huge amount of flexibility of use for this server. You could, for instance, change the FTP server so that it addresses the Registry and not the file system. You could even get it to address a database, or could use it as an external interface to access data in a large application.

Limitations

There is one limitation of the system:

  1. "ABOR" doesn't work (abortion from downloading/uploading files). Basically, the send and receive are done on the same thread as the commands instead of a seperate one. There's no reason why this can't be changed.

References

The vast majority of the information for building this site came from http://cr.yp.to/ftp.html, which is a really excellent source.

Conclusion

The FTP server is pretty much self explanatory, really. I don't think I need to add anything else here. And, how did I find C#? Well, considering I had an operational FTP server inside of two days, without knowing what the protocol was when I started, I'm really impressed. It's taken me a while to realise how good C# is (especially when taken with C++ .NET assemblies), but I'm a big fan now.

I hope you find this code useful.



About the Author

David McClarnon

He first encountered Windows programming using Visual C++/MFC version 1.5 on Windows 3.11 a very long time ago. He is now a contract developer specialising in .NET/native interop with p/invoke.

Downloads

Comments

  • Unable to upload files

    Posted by Cristian H. on 03/21/2013 01:53pm

    Hi, I am trying to upload a file to the FTP server, from another C# application: System.IO.Stream _Stream = _FtpWebRequest.GetRequestStream(); but I always get this error: "The remote server returned an error: (220) 220 Password ok, FTP server ready" This is not an error, but only a message. Could you please help me? Thank you!

    Reply
  • License?

    Posted by William Rawls on 09/18/2012 03:03pm

    Is this code licensed for use under any particular license? (GNU, Berkley, PHP, etc)

    Reply
  • Cross threaded error... m_listBoxMessages

    Posted by Fonz on 04/04/2012 03:55am

    Mainform.cs method MessageHandler_Message line 198 I get a cross threaded exception. I fixed it this way... Can also use the check m_listBoxMessages.InvokeRequired .... private void MessageHandler_Message(int nId, string sMessage) { try { m_listBoxMessages.BeginUpdate(); int nItem = m_listBoxMessages.Items.Add(string.Format("({0}) {2}", nId, System.DateTime.Now, sMessage)); if (m_listBoxMessages.Items.Count 5000) { m_listBoxMessages.Items.RemoveAt(0); } if (m_listBoxMessages.SelectedIndex

    Reply
  • append file corrupts files - here is the fix

    Posted by giopin on 04/28/2011 09:55am

    AppendCommandHandler.cs - line 39
    
    original:
    while (nReceived > 0)
    {
        nReceived = socketReply.Receive(abData);
        file.Write(abData, nReceived);
    }
    
    fixed:
    while (nReceived > 0)
    {
        file.Write(abData, nReceived);
        nReceived = socketReply.Receive(abData);
    }

    Reply
  • Another bug: CFtpServer.cs

    Posted by broj137 on 04/28/2011 03:11am

    The problem is m_apConnections.Count, because it is in the for weather, and it's not fixed. for each handler.Stop() it is decrased for one, so we have situation to remove only half of opened connections.
    
    
    public void Stop()
    		{
    			for (int nConnection = 0 ; nConnection < m_apConnections.Count; nConnection++)
    			{
    				FtpSocketHandler handler = m_apConnections[nConnection] as FtpSocketHandler;
    				handler.Stop();
    			}
    
    			m_socketListen.Stop();
    			m_theThread.Join();
    		}
    
    one possible solution:
    
    public void Stop()
    		{
                            for (int connCnt = m_apConnections.Count - 1; connCnt >= 0; connCnt--)
    			{
    				FtpSocketHandler handler = m_apConnections[connCnt] as FtpSocketHandler;
    				handler.Stop();
    			}
    
    			m_socketListen.Stop();
    			m_theThread.Join();
    		}

    Reply
  • How do you?

    Posted by ThePlague122 on 08/07/2010 08:23pm

    How do you compile these dlls... plz help.

    • Re : How do you compile these dlls

      Posted by darwen on 08/08/2010 08:36am

      Open the solution file in the app folder (csftp.sln), let visual studio convert it and then just build.

      Reply
    Reply
  • Great Article

    Posted by krishm on 10/31/2008 06:18am

    Hi Darwen I just read ur article n downloaded ur code n I really wanted to tell u that its a great article and helped me a lot. I was wondering if u cud also come uo with something about changing the permission of the files on the server. Thanks and Regards Krishnendu Mukherjee

    Reply
  • Good job

    Posted by zombi82 on 02/15/2007 05:55am

    Jasny i przejrzysty kod serwera FTP, najlepszy jaki znalazEem w necie. Thanks darwen.

    Reply
  • I find a little error in this program

    Posted by dragon829 on 08/22/2006 03:38am

    In this program,whether choose an item to remove a user,it will show messagebox ,is it a little error?I correct it as follow: 
    private void m_buttonRemoveUser_Click(object sender, System.EventArgs e)
    		{
    			if (m_listViewUsers.SelectedItems.Count == 0)
    			{
    				MessageBox.Show("Please select a user in the list", "CSFtp");
    			}
    			else
    			{
    				for (int nIndex = 0 ; nIndex < m_listViewUsers.SelectedItems.Count ; nIndex++)
    				{
    					ListViewItem item = m_listViewUsers.SelectedItems[nIndex];
    
    					string sUser = item.SubItems[0].Text;
    					Assemblies.Ftp.UserData.Get().RemoveUser(sUser);
    					m_listViewUsers.Items.Remove(item);
    				}
    			}	
    		}

    Reply
  • Updates

    Posted by darwen on 08/22/2005 04:37pm

    The Assemblies.General C++.NET dll has now been removed and replaced with a C# assembly with full source. Also the problem with localhost connection has been addressed (thanks jgorlick).

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: May 7, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT This eSeminar will explore three popular games engines and how they empower developers to create exciting, graphically rich, and high-performance games for Android® on Intel® Architecture. Join us for a deep dive as experts describe the features, tools, and common challenges using Marmalade, App Game Kit, and Havok game engines, as well as a discussion of the pros and cons of each engine and how they fit into your development …

  • The exponential growth of data, along with virtualization, is bringing a disruptive level of complexity to your IT infrastructure. Having multiple point solutions for data protection is not the answer, as it adds to the chaos and impedes on your ability to deliver consistent SLAs. Read this white paper to learn how a more holistic view of the infrastructure can help you to unify the data protection schemas by properly evaluating your business needs in order to gain a thorough understanding of the applications …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds