4

System.Net.WebException:服务器响应 PASV 命令返回的地址与建立 FTP 连接的地址不同。
在 System.Net.FtpWebRequest.CheckError()
在 System.Net.FtpWebRequest.SyncRequestCallback(Object obj)
在 System.Net.CommandStream.Abort(Exception e)
在 System.Net.FtpWebRequest.FinishRequestStage(RequestStage 阶段)
在 System.Net .FtpWebRequest.GetRequestStream()
在 BackupDB.Program.FTPUploadFile(String serverPath, String serverFile, FileInfo LocalFile, NetworkCredential Cred) 在 D:\PROJEKTI\BackupDB\BackupDB\Program.cs:line 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();
}
4

5 回答 5

8

我的天啊。购买他们的 3rd 方解决方案而不是通知您更改一行代码的所有迎合行为是怎么回事?

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

    request.UsePassive = false;

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

我注意到如果我通过我们的防火墙,那么我需要将其保留为 True,否则它将返回异常:

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

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

服务器响应 PASV 命令返回的地址与建立 FTP 连接的地址不同。

如果这可行并且您想让您的解决方案更具适应性,您可以使用默认 True 值将您的请求包装在 try-catch 块中,如果您收到 500 错误,则将 UsePassive 切换为 False 并重试。

于 2012-10-11T23:00:22.503 回答
3

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

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

于 2010-04-27T08:47:13.440 回答
3

在被动模式下,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 是否可以使用类似的解决方法。

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

于 2010-09-10T15:24:52.143 回答
2

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

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

于 2013-08-23T11:33:32.100 回答
2

您的 FTP 服务器配置错误。

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

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


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

request.UsePassive = false;

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


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

于 2017-10-26T06:55:12.777 回答