T
Tsahi Asher
hi,
I have a windows service which connects to various FTP servers, and
sends them files, using the FtpWebRequest class. It works most of the
time, because almost all of them use passive mode.
One server, however, uses active (or Port) mode.
A short explanation about passive vs. active mode: FTP uses two
channels, one for control and one for data. the control channel
usually uses port 21 on the server. the data channel will use some
random port negotiated between the two sides. in passive mode, the
client will send the server the PASV command, and the the server will
reply with the IP and port the client should connect to send or
receive the data. in active mode, the client will send the PORT
command, with the IP and port the server should connect to in order to
send or receive the data.
my problem is, that when UsePassive is false, the FtpWebRequest sends
the PORT command with the IP 127.0.0.1, instead of the external IP, so
the server replies with "Invalid PORT Command" and the connection
closes. I found this by adding trace listeners in the app.config.
the service runs on the SYSTEM account. i tried running it on the
NetworkService account, but that didn't change anything. the same
code, running from a web site (under the ASPNET account i assume)
sends the external IP with the PORT command (or at least used to until
recently. this appear to revert to 127.0.0.1 too somehow in recent
days.)
any idea on what's causing this, or how to force FtpWebRequest to use
the external IP?
note that i have no control over that server, so i can't change it to
passive. it probably has some firewall problem, because when i try to
connect in passive mode, it replies to the STOR command (which starts
the file upload) with "Can't open data connection". the server appears
to be the one microsoft provides with IIS. it replies with "Microsoft
FTP Service" to the initial connection.
the code is quite trivial, and looks like this:
ftpRequest =
(FtpWebRequest)FtpWebRequest.Create(ReceiveDetails + "/" + fileName);
ftpRequest.UsePassive = usePassive;
ftpRequest.KeepAlive = false;
ftpRequest.UseBinary = true;
ftpRequest.Credentials = new
NetworkCredential(UserName, Password);
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
FileInfo ff = new FileInfo(exportFileName);
byte[] fileContents = new byte[ff.Length];
using (FileStream fr = ff.OpenRead())
{
fr.Read(fileContents, 0,
Convert.ToInt32(ff.Length));
}
using (Stream writer = ftpRequest.GetRequestStream())
{
writer.Write(fileContents, 0,
fileContents.Length);
}
ftpRequest.GetResponse();
I have a windows service which connects to various FTP servers, and
sends them files, using the FtpWebRequest class. It works most of the
time, because almost all of them use passive mode.
One server, however, uses active (or Port) mode.
A short explanation about passive vs. active mode: FTP uses two
channels, one for control and one for data. the control channel
usually uses port 21 on the server. the data channel will use some
random port negotiated between the two sides. in passive mode, the
client will send the server the PASV command, and the the server will
reply with the IP and port the client should connect to send or
receive the data. in active mode, the client will send the PORT
command, with the IP and port the server should connect to in order to
send or receive the data.
my problem is, that when UsePassive is false, the FtpWebRequest sends
the PORT command with the IP 127.0.0.1, instead of the external IP, so
the server replies with "Invalid PORT Command" and the connection
closes. I found this by adding trace listeners in the app.config.
the service runs on the SYSTEM account. i tried running it on the
NetworkService account, but that didn't change anything. the same
code, running from a web site (under the ASPNET account i assume)
sends the external IP with the PORT command (or at least used to until
recently. this appear to revert to 127.0.0.1 too somehow in recent
days.)
any idea on what's causing this, or how to force FtpWebRequest to use
the external IP?
note that i have no control over that server, so i can't change it to
passive. it probably has some firewall problem, because when i try to
connect in passive mode, it replies to the STOR command (which starts
the file upload) with "Can't open data connection". the server appears
to be the one microsoft provides with IIS. it replies with "Microsoft
FTP Service" to the initial connection.
the code is quite trivial, and looks like this:
ftpRequest =
(FtpWebRequest)FtpWebRequest.Create(ReceiveDetails + "/" + fileName);
ftpRequest.UsePassive = usePassive;
ftpRequest.KeepAlive = false;
ftpRequest.UseBinary = true;
ftpRequest.Credentials = new
NetworkCredential(UserName, Password);
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
FileInfo ff = new FileInfo(exportFileName);
byte[] fileContents = new byte[ff.Length];
using (FileStream fr = ff.OpenRead())
{
fr.Read(fileContents, 0,
Convert.ToInt32(ff.Length));
}
using (Stream writer = ftpRequest.GetRequestStream())
{
writer.Write(fileContents, 0,
fileContents.Length);
}
ftpRequest.GetResponse();