Sign in to follow this  

[.net] FTP protocol... LIST response?

This topic is 2555 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm building myself an FTP server, and I did alright until I got to the LIST command. I'm testing against the FileZilla client, and for some reason it insists on sending me LIST even though I've specified that my server supports MLSD.

No matter what I do, I can't get the client to accept my directory listing.
Here's the code:

                public static void HandleLISTCmd(string FTPCommand, FTPClient Client)
Client.Send(Encoding.ASCII.GetBytes("150 Opening binary data connection for file list\0"));

/*MemoryStream EPLFStream = new MemoryStream();
BinaryWriter Writer = new BinaryWriter(EPLFStream);

string[] Files = Directory.GetFiles(GlobalSettings.Default.WorkingDirectory);

foreach (string Fle in Files)




foreach (string Fle in Directory.GetFiles(GlobalSettings.Default.WorkingDirectory))
string FInfo = GenerateFileInfo(Fle);

//By now the filetransfer should be complete, so let the client know...
Client.Send(Encoding.ASCII.GetBytes("226 Transfer complete.\0"));

private static string GenerateFileInfo(string Filepath)
FileInfo FInfo = new FileInfo(Filepath);

string Size = FInfo.Length.ToString();
TimeSpan TSpan = (FInfo.LastWriteTime - new DateTime(1970, 1, 1));
string Modified = TSpan.TotalSeconds.ToString();

string ReturnStr = "+s" + Size + ",m" + Modified + ",r," + "\t" + FInfo.Name + "\0";

return ReturnStr;

private static string GenerateBinLS(string Filepath)
FileInfo FInfo = new FileInfo(Filepath);
string Result = "rw-r--r-- 1 owner group ";

Result += RightAlignString(FInfo.Length.ToString(), 13, ' ') + " ";
Result += GetMonth(FInfo.LastWriteTime.Month) + " ";

if (FInfo.LastWriteTime.Day.ToString().Length > 2)
Result += FInfo.LastWriteTime.Day.ToString() + " ";
else if (FInfo.LastWriteTime.Day.ToString().Length == 1)
Result += " " + FInfo.LastWriteTime.Day.ToString() + " ";
Result += " " + FInfo.LastWriteTime.Day.ToString() + " ";

Result += FInfo.LastWriteTime.Hour.ToString() + ":" + FInfo.LastWriteTime.Minute.ToString() + " ";

Result += FInfo.Name;

return Result;

private static string GetMonth(int Month)
switch (Month)
case 1:
return "Jan";
case 2:
return "Feb";
case 3:
return "Mar";
case 4:
return "Apr";
case 5:
return "May";
case 6:
return "Jun";
case 7:
return "Jul";
case 8:
return "Aug";
case 9:
return "Sep";
case 10:
return "Oct";
case 11:
return "Nov";
case 12:
return "Dec";

return "";

private static string RightAlignString(string sString, int nWidth, char cDelimiter)
System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();

for (int nCharacter = 0; nCharacter < nWidth - sString.Length; nCharacter++)

return stringBuilder.ToString();

I've tried using both GenerateFileInfo() and GenerateBinLS() to generate my LIST response, but no matter which one I use I get an error about the connection having timed out and that the client couldn't receive my directory listing.
I've read that the server is supposed to close the data connection, but when I try to do that FileZilla complains that the server has closed the connection.

Here is how I open my data connection:

         /// <summary>
/// Handles a PASV command in the FTP protocol.
/// PASV asks the server to open a port for data-transfer and send
/// it to the client so it can connect.
/// </summary>
/// <param name="FTPCommand"></param>
/// <param name="IP"></param>
/// <param name="Client"></param>
public static void HandlePASVCmd(string FTPCommand, string IP, FTPClient Client)
IP = IP.Replace(".", ",");

if (Client.OpenDataPort((PortNum1 * 256 + PortNum2).ToString()))
Client.Send(Encoding.ASCII.GetBytes("227 Entering Passive Mode (" + IP + "," + CalculatePort() + ")\0"));
else //This should technically never occur. See
//for error codes.
Client.Send(Encoding.ASCII.GetBytes("425 Cannot open data connection!\0"));

private static int PortNum1 = 10;
private static int PortNum2 = 10;

private static string CalculatePort()
//The calculation is PortNum1 x 256 + PortNum2
//26100 is the port being used to listen for initial FTP connections.
if ((PortNum1 * 256) + PortNum2 != 26100)
string Result = PortNum1.ToString() + "," + PortNum2.ToString();


return Result;
PortNum1 = PortNum1 + 2;
PortNum2 = PortNum2 + 2;
return PortNum1.ToString() + "," + PortNum2.ToString();


       public bool OpenDataPort(string Port)
IPHostEntry HostEntry = Dns.GetHostByName(Dns.GetHostName());
IPAddress Address = HostEntry.AddressList[0];
Logger.LogDebug("DataAddress: " + Address.ToString());
IPEndPoint LocalEP = new IPEndPoint(Address, int.Parse(Port));

m_DatListenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
m_ConnectingWaitEvent = new AutoResetEvent(false);

//Don't need a high backlog, since we'll only be listening for one incoming connection.
m_DatListenerSocket.BeginAccept(new AsyncCallback(OnAcceptDataconnection), m_DatListenerSocket);
catch (SocketException)
return false;

return true;

private void OnAcceptDataconnection(IAsyncResult AR)
Socket AcceptedSocket = m_DatListenerSocket.EndAccept(AR);

if (AcceptedSocket != null)
AcceptedSocket.Blocking = false;
m_DatSenderSocket = AcceptedSocket;

Can someone please help me out? :)

Share this post

Link to post
Share on other sites
Original post by MatsVed
I'm doing that!

Sry I assumed that 'Client' reference in your first block of code was a Socket object and your control channel. I would recommend logging everything you write to your control and data channels and examining that. You might also try executing client commands against a server that you know works and mimic its output. FTP is really old and as you probably noticed the documentation is ... unhelpful.

Share this post

Link to post
Share on other sites

This topic is 2555 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this