我在 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
行(return
语句之外)的 FtpWebRequest.GetResponse()
调用处引发,没有其他任何异常在堆栈跟踪中:
System.Net.WebException
: Unable to connect to the remote server
atSystem.Net.FtpWebRequest.GetResponse()
at (that line number in that file)
我的测试工具(有效)和生产环境(无效)之间唯一真正的区别是生产环境中存在防火墙 - 所有四台服务器都位于略有不同的子网中:
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 客户端到 Prod 服务器进行 FTP,但不是以编程方式。
我尝试更改 UsePassive
的 bool
appSettings 值,这没有什么区别,并且在每种情况下,FTP 服务器日志中都没有显示任何内容(所以它是还没有走到那一步)。
现在,我并不期望任何人能够调试我的托管环境的硬件基础设施,但我正在努力思考我还可以做哪些改变来使其正常工作。我已经看到它在我的测试工具中本地工作,调用相同的方法。如果有帮助的话,测试工具代码如下:
[NUnit.Framework.Test]
public void FtpFileListTest()
{
ICollection<string> files = MediaSyncDaemon.GetFilesToFetch();
Assert.IsNotNull(files);
Assert.Greater(files.Count, 0);
}
请问有人知道我还可以尝试什么吗?
谢谢!
更新
在评论中提出了一些值得一看的地方的建议后,我可以进一步更新:
问题似乎不是用户权限问题 - 服务在本地系统帐户的上下文中运行(has more permissions than Administrator 就是这样)
问题似乎不是代码访问安全性。我添加了
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。
有人对我可以尝试的事情有任何进一步的建议吗?
最佳答案
我想分享一下我们的问题和解决方案: 我们无法在公司 PC 上使用 ftpwebrequest 连接到 FTP 服务器,但在我们的 PC 上它可以正常工作。 问题在于 ftpwebrequest() 正在获取公司 IT 强制在 PC 上的代理配置。 为了解决这个问题,我们添加了(ftpwebrequest object).proxy = null;连接之前。
关于c# - FtpWebRequest Web异常: "Unable to connect to the remote server",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14714815/