【问题标题】:FtpWebRequest WebException: "Unable to connect to the remote server"FtpWebRequest WebException:“无法连接到远程服务器”
【发布时间】:2013-01-20 19:26:04
【问题描述】:

我在 Windows 服务中有代码,当我通过测试工具在本地运行它时成功连接到 FTP 服务器(FTP 服务器位于本地网络上的另一台机器上)。

但是,当我在生产托管环境中安装它时,我得到了可怕的 WebException “无法连接到远程服务器”。我是否使用ACTV or PASV FTP 似乎并不重要,我得到的只是这个WebException。但是,如果我尝试从 Windows 命令行 FTP,它工作得非常好(所以不是防火墙有问题)。

我使用的代码(改编自How to List Directory Contents with FTP in C#?)如下:

private static readonly string __ftpSourceServer = "ftp://"
  + ConfigurationManager.AppSettings["FtpServer"] + "/";
private static readonly NetworkCredential __ftpCreds = new NetworkCredential(
  ConfigurationManager.AppSettings["Username"],
  ConfigurationManager.AppSettings["Password"]);

// And now the method MediaSyncDaemon.GetFilesToFetch:
bool usePassive = Boolean.TryParse(ConfigurationManager.AppSettings["UsePassive"]
  , out usePassive) && usePassive;

Uri ftpSrv = new Uri(__ftpSourceServer + Uri.EscapeUriString(
  ConfigurationManager.AppSettings["FtpPath"]));
Logger.Debug("Connecting to FTP server at " + ftpSrv + "; PASV? " + usePassive);

FtpWebRequest listRequest = (FtpWebRequest) WebRequest.Create(ftpSrv);
listRequest.Method = WebRequestMethods.Ftp.ListDirectory;
listRequest.Credentials = __ftpCreds;
listRequest.UsePassive = usePassive;
listRequest.UseBinary = false;

using (FtpWebResponse listResponse = (FtpWebResponse) listRequest.GetResponse())
{
    // ReSharper disable AssignNullToNotNullAttribute
    return new StreamReader(listResponse.GetResponseStream())
        .ReadToEnd().Split(new[] { '\n', '\r' },
            StringSplitOptions.RemoveEmptyEntries)
        .Where(s => s.EndsWith(".zip", true, CultureInfo.InvariantCulture))
        .ToList();
    // ReSharper restore AssignNullToNotNullAttribute
}

using 行中的FtpWebRequest.GetResponse() 调用(return 语句之外)抛出异常,堆栈跟踪中没有其他内容:

System.Net.WebException: 无法连接到远程服务器
System.Net.FtpWebRequest.GetResponse()
在(该文件中的行号)

我的测试工具(有效)和生产环境(无效)之间唯一真正的区别是生产环境中存在防火墙——所有四台服务器都位于稍微不同的子网上:

Dev client    10.16.6.155     subnet 255.255.255.128
Dev server    10.16.7.242     subnet 255.255.255.0
Prod client   192.168.102.107 subnet 255.255.255.0
Prod server   192.168.203.110 subnet 255.255.255.0

但防火墙不是问题,我可以交互式地从 Prod 客户端 FTP 到 Prod 服务器,只是不能以编程方式。

我已尝试将 bool appSettings 的值更改为 UsePassive,但这并没有什么区别,而且在每种情况下,FTP 服务器日志中都没有显示任何内容(所以它没有走那么远)。

现在我不希望任何人能够调试我的托管环境的硬件基础架构,但我正在努力思考我还可以改变什么来让它工作。我已经看到它在我的测试工具中本地工作,调用相同的方法。如果有帮助,测试工具代码如下:

[NUnit.Framework.Test]
public void FtpFileListTest()
{
    ICollection<string> files = MediaSyncDaemon.GetFilesToFetch();
    Assert.IsNotNull(files);
    Assert.Greater(files.Count, 0);
}

请问有人知道我还能尝试什么吗?

谢谢!


更新

已经有一些关于在 cmets 中查看位置的建议,我可以进一步更新一下:

  1. 问题似乎不是用户权限——服务在本地系统帐户的上下文中运行(has more permissions than Administrator 确实如此)

  2. 问题似乎不在于代码访问安全性。我已经为这段代码的入口方法添加了一个SocketPermission.Demand 调用:

    System.Security.CodeAccessPermission socketPermission;
    socketPermission = new SocketPermission(NetworkAccess.Connect,
      TransportType.Tcp, ConfigurationManager.AppSettings["FtpServer"], 20);
    socketPermission.Demand();
    socketPermission = new SocketPermission(NetworkAccess.Connect,
      TransportType.Tcp, ConfigurationManager.AppSettings["FtpServer"], 21);
    socketPermission.Demand();
    

    我没有看到任何SecurityException 被抛出;在相同代码位置的新行号处,我仍然得到相同的 WebException。

有人对我可以尝试什么有任何进一步的建议吗?

【问题讨论】:

  • 我强烈怀疑是代码正在运行的用户,因为不允许进行出站网络连接。
  • 啊,谢谢(那很快!)。我将如何测试(或者,更好的是,授予该访问权限)?
  • 你能用 Wireshark 询问生产环境吗?您将能够确定它是否达到了实际发出请求的程度,然后可能更容易识别它是否是权限问题。
  • 我认为如果我在生产服务器上安装 Wireshark,我们的安全审计员会很生气。我将如何授予对代码的访问权限?或者,我将如何以编程方式要求访问(在这种情况下,我会看到 SecurityException,对吗?)?
  • @Owen,谢谢我的修复了。实际问题在于某些 DNS 解析。我们使用主机名来构建 FTP url。但是 DNS 解决这个问题存在一些问题,因此导致了这个错误

标签: c# ftpwebrequest system.net.webexception


【解决方案1】:

我想分享我们的问题和解决方案: 我们无法在公司 PC 上使用 ftpwebrequest 连接到 FTP 服务器,但在我们的 PC 上它可以正常工作。 问题是 ftpwebrequest() 正在获取公司 IT 在 PC 上强制执行的代理配置。 为了解决这个问题,我们添加了 (ftpwebrequest object).proxy = null;在连接之前。

【讨论】:

    猜你喜欢
    • 2011-04-29
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    相关资源
    最近更新 更多