テスト ハーネスを使用してローカルで実行すると (FTP サーバーがローカル ネットワーク上の別のマシン上にある場合)、FTP サーバーに正常に接続する Windows サービスのコードがあります。
ただし、本番ホスティング環境にインストールすると、恐ろしいWebException「リモートサーバーに接続できません」が発生します。ACTV
私が使用しているか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
}
例外は、行内 (ステートメントの外側) のFtpWebRequest.GetResponse()
呼び出しでスローされ、スタック トレースには他に何もありません。using
return
System.Net.WebException
: リモート サーバーに接続できませんSystem.Net.FtpWebRequest.GetResponse()
(そのファイルのその行番号)
テスト ハーネス (動作する) と実稼働環境 (動作しない) の唯一の実際の違いは、実稼働環境にファイアウォールが存在することです。4 つのサーバーはすべてわずかに異なるサブネット上にあります。
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できるため、ファイアウォールが問題になることはありません。
bool
appSettings の値を変更してみましたUsePassive
が、違いはありません。いずれの場合も、FTP サーバーのログには何も表示されません (そのため、それほど進んでいません)。
現在、ホスティング環境のハードウェア インフラストラクチャをデバッグできる人がいるとは思っていませんが、これを機能させるために他に何を変更できるかを考えるのに苦労しています。同じメソッドを呼び出して、テスト ハーネスでローカルに動作することを確認しました。参考までに、テスト ハーネス コードは次のようになります。
[NUnit.Framework.Test]
public void FtpFileListTest()
{
ICollection<string> files = MediaSyncDaemon.GetFilesToFetch();
Assert.IsNotNull(files);
Assert.Greater(files.Count, 0);
}
他に何を試すことができるか考えている人はいますか?
ありがとう!
アップデート
コメントを参照する場所のいくつかの提案があったので、これをもう少し更新できます。
問題はユーザーのアクセス許可ではないようです — サービスはローカル システム アカウントのコンテキストで実行されています (管理者よりも多くのアクセス許可を持っています) 。
問題は、コード アクセス セキュリティではないようです。このコード チャンクのエントリ メソッドへの呼び出しを追加しました。
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 をまだ取得しています。
私が試すことができることについて、他に何か提案はありますか?