Hello,
While evaluating the latest version of the FTP libary for .NET I came accross the following behaviour that can be simulated by following the steps down below. Please let me know if there's a fix available for this issue -
Problem: Very small files (1 - 2 charactes, or 4 bytes - for instance) are randomly downloaded empty, w/o errors being generated. The higher the connection speed to the FTP server, the higher the occurence rate. For an FTP server part of the LAN - we get about 15% of the files empty
How to reproduce the behaviour: (1) use a source FTP server with a high connection speed [I used FileZilla on a LAN server because I wanted to test implicit SSL]; (2) Have available on the FTP server several very small files, say 4 bytes each - we'll attempt to download them in a single session [I used 100 text files, each having just 2 characters as the body of the file] (3) download all these files locally, one at a time, by name - as part of the same session. You'll end up with about 15% of the files which are empty (size=0), and no errors raised on either end (server, or client).
Here's the code that I used to simulate the behaviour. Thanks for your help --
class TestConsole
{
static void Main(string[] args)
{
FtpClient ftpSession = new FtpClient();
ftpSession.TraceWriter =
Console.Out;
ftpSession.CertificateReceived +=
new CertificateReceivedEventHandler(ftpSession_CertificateReceived);
int hostport = 990;
ftpSession.Connect(
"your FTPS Server IP address", hostport, AuthenticationMethod.Tls, VerificationFlags.None, null);
ftpSession.SendCustomCommand(
"PROT P");
ftpSession.Login(
"your user name", "your password");
ftpSession.ChangeCurrentFolder(
"upload");
ftpSession.ListingParsers.Clear();
ftpSession.ListingParsers.Add(
new FtpUnixListingParser());
FtpItemInfoList items = ftpSession.GetFolderContents();
foreach (FtpItemInfo item in items)
{
if (item.Type == FtpItemType.File)
{
string dnloadRemoteName = item.Name + ".dload";
string dnloadLocalName = "c:\\temp\\" + dnloadRemoteName;
ftpSession.RenameFile(item.Name, dnloadRemoteName);
ftpSession.ReceiveFile(dnloadRemoteName, dnloadLocalName);
AbstractFile localFile = new DiskFile(dnloadLocalName);
if (localFile.Size > 0)
{
localFile.Name = localFile.Name +
".txt";
ftpSession.DeleteFile(dnloadRemoteName);
}
}
}
ftpSession.Disconnect();
ftpSession.CertificateReceived -=
new CertificateReceivedEventHandler(ftpSession_CertificateReceived);
}
static void ftpSession_CertificateReceived(object sender, CertificateReceivedEventArgs e)
{
e.Action =
VerificationAction.Accept;
}
}