I am having a problem connecting a Windows service to an FTP site.
I inherited a Windows service from another developer. The service connects to a 3rd party server, downloads a csv file and then processes it. For some reason, the service stopped working (well over a year ago, before I was given the project).
So I went back to basics, created a console app and tried the connection/ file download function only in that app. I have tried many different methods to connect to the FTP, but all of them return the same error to my application:
The remote server returned an error: 227 Entering Passive Mode ()
This is one of the many methods I've tried:
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://ftpaddress/filename.csv");
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = new NetworkCredential("username", "password");
request.UsePassive = true;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
Console.WriteLine(reader.ReadToEnd());
Console.WriteLine("Download Complete, status {0}", response.StatusDescription);
reader.Close();
response.Close();
But it falls down on this part:
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
I read in several forums that setting the UsePassive property to False fixes these errors, but all that happened to me was that I got a syntax error instead, as below:
The remote server returned an error: (500) Syntax error, command unrecognized.
The file is hosted on a 3rd party FTP server I have no control over. I can paste the URL into a browser, and I am prompted for a username and password, which then allows me through and I can download the file.
To eliminate our firewall as the cause of the problem, I ran the app on both the internal network and the WiFi (which isn't behind the firewall), and it makes no difference. I also connected through FileZilla in Default, Active and Passive modes, and it worked every time. So no problem there.
So then I ran Wireshark. Here is an image of the wire capture using Filezilla (i.e. a successful one), in Passive mode:
And here is the capture when connecting (and failing) using the app, with passive set to true:
So as you can see in the failed connection above, I can log in to the server just fine. Then for whatever reason an extra request is sent, namely "TYPE I", which prompts the response of "Switching to binary mode." The below that, I get the following:
500 oops: vsf_sysutil_recv_peek: no data
In addition, I also ran it again after setting the Passive property to false, and this is what I got that time:
So my question is twofold;
1, if I somehow get past the UsePassive issue and set that property to false, will that solve my problem?
2, ignoring the UsePassive property, why can't I download the file from the app, but can from everywhere else?
227 FTP Response code This is the response given by the server to the PASV command. It indicates that the server is ready for the client to connect to it for the purpose of establishing a data connection.
The issue is now resolved. It turned out to be Kaspersky's built-in firewall that was blocking the connection. It's annoying that it didn't present me with a warning when I tried to connect, but reassuring to know my PC is safe.
The clue was in the detail of the 227 return:
10051 – A socket operation was attempted to an unreachable network
Also, for anyone reaching this via Google etc, the remote server was configured to only allow Passive connections, which is why I was getting the 500 syntax error. Studying a Wire capture when downloading a file revealed that Filezilla actually reverts to Passive mode automatically if Active is selected but fails.
The code in my original post works fine now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With