服务器返回一个地址以响应PASV命令,该命令与进行FTP连接的地址不同

System.Net.WebException:服务器返回一个地址以响应PASV命令,该命令与进行FTP连接的地址不同。
在System.Net.FtpWebRequest.CheckError()
在System.Net.FtpWebRequest.SyncRequestCallback(Object obj)
在System.Net.CommandStream.Abort(例外e)
在System.Net.FtpWebRequest.FinishRequestStage(RequestStage阶段)
在System.Net.FtpWebRequest.GetRequestStream()
在D:\ PROJEKTI \ BackupDB \ BackupDB \ Program.cs中的BackupDB.Program.FTPUploadFile(String serverPath,String serverFile,FileInfo LocalFile,NetworkCredential Cred):第119行

码:

FTPMakeDir(new Uri(serverPath + "/"), Cred); FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverPath+serverFile); request.UsePassive = true; request.Method = WebRequestMethods.Ftp.UploadFile; request.Credentials = Cred; byte[] buffer = new byte[10240]; // Read/write 10kb using (FileStream sourceStream = new FileStream( LocalFile.ToString(), FileMode.Open)) { using (Stream requestStream = request.GetRequestStream()) { int bytesRead; do { bytesRead = sourceStream.Read(buffer, 0, buffer.Length); requestStream.Write(buffer, 0, bytesRead); } while (bytesRead > 0); } response = (FtpWebResponse)request.GetResponse(); response.Close(); } 

我的天啊。 在这里购买他们的第三方解决方案而不是通知您更改一行代码的所有内容是什么?

尝试切换Passive值以查看哪些有效:

  request.UsePassive = false; 

这可能取决于计算机(客户端和服务器)之间的防火墙。

我注意到如果我通过我们的防火墙,然后我需要它保持为True,否则它将返回exception:

远程服务器返回错误:(500)语法错误,命令无法识别。

但是,如果我在防火墙后面(就像在数据中心内直接相互连接的两台机器)那么我需要将其设置为False,否则它将返回Exception:

服务器返回一个地址以响应PASV命令,该命令与进行FTP连接的地址不同。

如果这样做并且您希望使解决方案更具适应性,则可以使用默认的True值将请求包装在try-catch块中,如果出现500错误,则将UsePassive切换为False并再次尝试。

如果有人有同样的问题,这是proftpd的解决方案

http://www.proftpd.org/docs/howto/NAT.html

在被动模式下,FTP会话如下:

 client: PASV (i would like to transfer files. Tell me which port and ip address should I use) server: 227 Entering Passive Mode (172,16,3,4,204,173) (ok, use port 52397 on IP address 172.16.3.4.) client: connects to this IP address/port and starts data transfer. 

看起来具有两个公共IP地址(例如1.2.3.4)的FTP服务器返回私有IP地址作为对PASV命令的响应。

切换到活动模式。

在活动模式下,FTP服务器连接到FTP客户端以进行数据传输。 它可以解决这个问题,但不是防火墙友好的。 当传入连接被阻止时(非常常见)它将无法工作。

忽略IP地址作为对PASV命令的响应发送

如果公共ftp服务器IP地址是公共IP地址,则作为PASV命令响应返回的IP地址来自私有范围(例如10.,192.168。)。 在这种情况下,FTP客户端应使用公共IP地址。

这正是我们的Rebex FTP在这种情况下所做的事情。 它运作良好(可以关闭此行为)。 甚至可以为具有多个公共IP地址的服务器打开它。

我不知道FtpWebRequest是否可以采用类似的解决方法。

您可以下载试用版并检查它是否能解决您的问题。

经过大量挖掘后,我发现解决此问题的唯一方法是更改​​服务器上的PASV设置。

幸运的是我控制了客户机和服务器机器,所以我能够告诉服务器(在我的情况下是FileZilla)使用公共IP而不是私有IP。

您的FTP服务器配置错误。

在被动模式下,服务器报告客户端应连接到的IP地址和端口以进行数据传输。 您的FTP服务器在内部网络中报告其IP地址,尽管它位于防火墙/ NAT之后。 由于显而易见的原因,客户端无法连接到该内部地址。 您必须配置FTP服务器以报告其外部IP地址。

如何完成是特定于服务器的,你没有告诉我们,你的FTP服务器是什么。

  • IIS:在IIS管理器中 ,打开FTP> FTP防火墙支持 。 请参阅我的安装IIS服务器指南中的外部防火墙/ NAT后面的 服务器部分 。
  • FileZilla FTP服务器: 进入编辑>设置>被动模式设置> IPv4特定>外部服务器IP地址,用于被动模式传输 。 请参阅通过NAT在端口2000上运行的FTP服务器不在被动模式下工作 。
  • ProFTPD:使用MasqueradeAddress指令 。
  • vsftpd: pasv_address指令 。

这里的一些答案建议使用主动模式。

 request.UsePassive = false; 

但这只有在客户端和服务器之间没有防火墙/ NAT的情况下才有帮助,在这种情况下,您首先不会遇到问题(除非服务器真的坏了并报告完全错误的IP地址,不仅仅是内部的)。 或者,如果防火墙/ NAT配置为允许入站连接,那么通常情况并非如此。


另一种方法是使用不同的FTP库,通过忽略服务器报告的错误IP地址并使用主/控制连接IP地址来解决问题。 或者使用EPSV命令而不是隐式使用主/控制连接IP地址的PASV命令。