Simple file transfer not working

Oct 7, 2015 at 4:30 PM
This should be easy but it just won't work.
Trying to download single file from a ftp server.

FileZilla can do it, no problem.

This is .NET code:
 using (FtpClient conn = new FtpClient())
                {
                    conn.Host = System.Configuration.ConfigurationManager.AppSettings["camera_ftp"];
                    string user = System.Configuration.ConfigurationManager.AppSettings["camera_user"];
                    string password = System.Configuration.ConfigurationManager.AppSettings["camera_password"];
                    conn.Credentials = new NetworkCredential(user, password);
                    string path = System.Configuration.ConfigurationManager.AppSettings["image_path"];
                    string file = System.Configuration.ConfigurationManager.AppSettings["image_name"];

                    conn.DataConnectionType = FtpDataConnectionType.PASV;

                    using (Stream istream = conn.OpenRead(path + "/" + file, FtpDataType.Binary))
                    {
                        try
                        {
                            // istream.Position is incremented accordingly to the reads you perform
                            // istream.Length == file size if the server supports getting the file size
                            // also note that file size for the same file can vary between ASCII and Binary
                            // modes and some servers won't even give a file size for ASCII files! It is
                            // recommended that you stick with Binary and worry about character encodings
                            // on your end of the connection.
                            int length = (int)conn.GetFileSize(path + "/" + file);
                            byte[] b = new byte[length];
                            istream.Read(b, 0, length);
                            return b;
                        }
                        finally
                        {
                            istream.Close();
                            
                        }
                    }
This is log output
InterNetwork: 212.42.162.144
220-Microsoft FTP Service
220 Welcome to www4.fast.net.uk
USER 5889aftp
331 Password required for 5889aftp.
PASS <omitted>
230-You are now connected - Please upload/download files
230 User logged in.
FEAT
211-Extended features supported:
 LANG EN*
 UTF8
 AUTH TLS;TLS-C;SSL;TLS-P;
 PBSZ
 PROT C;P;
 CCC
 HOST
 SIZE
 MDTM
 REST STREAM
211 END
Text encoding: System.Text.UTF8Encoding
OPTS UTF8 ON
200 OPTS UTF8 command successful - UTF8 encoding now ON.
InterNetwork: 212.42.162.144
220-Microsoft FTP Service
220 Welcome to www4.fast.net.uk
USER 5889aftp
331 Password required for 5889aftp.
PASS <omitted>
230-You are now connected - Please upload/download files
230 User logged in.
Text encoding: System.Text.UTF8Encoding
OPTS UTF8 ON
200 OPTS UTF8 command successful - UTF8 encoding now ON.
PWD
257 "/" is current directory.
CWD /
250 CWD command successful.
TYPE I
200 Type set to I.
SIZE /tmp/results/image.bmp
213 1155122
PASV
227 Entering Passive Mode (212,42,162,144,195,37).
InterNetwork: 212.42.162.144
RETR /tmp/results/image.bmp
125 Data connection already open; Transfer starting.
SIZE /tmp/results/image.bmp
213 1155122
550 The specified network name is no longer available. 
A first chance exception of type 'System.Net.FtpClient.FtpCommandException' occurred in System.Net.FtpClient.dll
QUIT
221 Thank you for using www4.fast.net.uk - You are now disconnected
Disposing FtpClient object...
Disposing FtpSocketStream...
Disposing FtpSocketStream...
Disposing FtpClient object...
QUIT
221 Thank you for using www4.fast.net.uk - You are now disconnected
Disposing FtpSocketStream...
RealCamera.Cameras: 2015-10-07 16:19:07,002 [1] ERROR RealCamera.Cameras - FTP exception: 
System.Net.FtpClient.FtpCommandException: The specified network name is no longer available. 
   at System.Net.FtpClient.FtpClient.CloseDataStream(FtpDataStream stream)
   at System.Net.FtpClient.FtpDataStream.Close()
   at RealCamera.Cameras.GetImage()
A first chance exception of type 'System.Net.FtpClient.FtpCommandException' occurred in RealCamera.dll
seems whatever I try I get the error "The specified network name is no longer available" - but the file is there!

What am I doing wrong?
Oct 7, 2015 at 4:53 PM
OK, done some more tests - seems to be related to file size

File of 7K will transfer
File of 24K won't

24K is rather small. Anyone suggest why there is this size limit and how to overcome it?
Oct 8, 2015 at 7:54 AM
Managed to fix this. This is the fix:
conn.DataConnectionType = FtpDataConnectionType.PASV;

                    file = path + "/" + file;
                    using (Stream istream = conn.OpenRead(file, FtpDataType.Binary))
                    {
                        try
                        {
                            byte[] b = new byte[1024];

                            using (MemoryStream output = new MemoryStream())
                            {
                                int read = 0;
                                do
                                {
                                    read = istream.Read(b, 0, b.Length);
                                    if (read > 0)
                                    {
                                        output.Write(b, 0, read);
                                    }
                                } while (read > 0);

                                return output.ToArray();
                            }

                        }
                        finally
                        {
                            istream.Close();
                            
                        }
                    }
i.e. read it a bit at a time
Coordinator
Mar 9, 2016 at 2:47 AM
Read the examples... don't try to allocate a buffer the size of the file, it's a bad idea even if the file is small. System.Net.FtpClient returns streams, read a chunk of data in at a time in a loop. None of the official examples advocate allocating a buffer and dumping all the data into it at once. Your buffer doesn't have to be 1 byte, it can be much larger.