サーバーは、FTP接続が作成されたアドレスとは異なるPASVコマンドに応じてアドレスを返しました

StackOverflow https://stackoverflow.com/questions/2709498

質問

System.net.Webexception:サーバーは、FTP接続が作成されたアドレスとは異なるPASVコマンドに応じてアドレスを返しました。
at system.net.ftpwebrequest.checkerror()
at System.net.ftpwebrequest.syncrequestcallback(オブジェクトobj)
at System.net.CommandStream.Abort(例外E)
at System.net.ftpwebrequest.finishrequeststage(request -stage stage)
at system.net.ftpwebrequest.getRequestStream()
backupdb.program.ftpuploadfile(string serverpath、string serverfile、fileinfo localfile、networkcredential cred)のd: projekti backupdb backupdb program.cs:行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();
}
役に立ちましたか?

解決 2

誰かが同じ問題を抱えている場合、これはProftpdのソリューションです

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

他のヒント

ああ、神様。コードの1行を変更するように通知するのではなく、サードパーティのソリューションを購入するために、ここですべてのパンダリングが起きていますか?

パッシブ値を切り替えて、どの動作を確認してください。

    request.UsePassive = false;

これは、マシン間のファイアウォール(クライアントとサーバー)に依存する場合があります。

ファイアウォールを通過した場合に気づきましたが、Trueに残っている必要があります。そうでなければ、例外を返します。

リモートサーバーはエラーを返しました:(500)構文エラー、コマンドは認識されていません。

ただし、ファイアウォールの背後にいる場合(データセンター内で互いに直接接続する2つのマシンなど)、それをfalseに設定する必要があります。そうしないと、例外が返されます。

サーバーは、FTP接続が行われたアドレスとは異なるPASVコマンドに応じてアドレスを返しました。

これが機能し、ソリューションをより適応性のあるものにしたい場合は、デフォルトの真の値を使用してリクエストをトライキャッチブロックにラップすることができます。500エラーが発生した場合は、UsePassiveにfalseに切り替えて再試行します。

パッシブモードでは、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.

2つのパブリックIPアドレス(1.2.3.4)を備えたFTPサーバーは、PASVコマンドへの応答としてプライベートIPアドレスを返しているようです。

解決

アクティブモードに切り替えます。

アクティブモードでは、FTPサーバーはデータ転送のためにFTPクライアントに接続します。この問題は解決しますが、ファイアウォールに優しいものではありません。着信接続がブロックされている場合は機能しません(非常に一般的です)。

IPアドレスを無視して、PASVコマンドへの応答として送信します

Public FTP Server IPアドレスが公開されている場合、PASVコマンドの応答として返されたIPアドレスは、プライベート範囲(10.、192.168など)からのものです。そのような場合、FTPクライアントはパブリックIPアドレスを使用する必要があります。

これがまさに私たちのものです Rebex FTP そのような状況で行う。うまく機能します(この動作はオフにすることができます)。複数のパブリックIPアドレスを備えたサーバーの場合でもオンにすることができます。

FTPWebRequestで同様の回避策が可能かどうかはわかりません。

あなたはできる ダウンロードトライアル そして、それがあなたの問題を解決するかどうかを確認してください。

多くの掘り下げの後、この問題を解決する唯一の方法は、サーバーのPASV設定を変更することでした。

幸いなことに、私はクライアントマシンとサーバーマシンの両方を制御するため、私はプライベートIPではなくパブリックIPを使用するようにサーバー(私の場合はFilezilla)に伝えることができました。

FTPサーバーは誤解されています。

パッシブモードでは、サーバーは、データ転送のためにクライアントが接続するIPアドレスとポートを報告します。 FTPサーバーは、ファイアウォール/NATの背後にありますが、内部ネットワーク内のIPアドレスを報告しています。クライアントは、明らかな理由でその内部アドレスに接続することはできません。外部IPアドレスを報告するには、FTPサーバーを構成する必要があります。

それがどのように行われるかはサーバー固有であり、あなたは私たちにあなたのFTPサーバーが何であるかを教えてくれませんでした。


ここでのいくつかの答えは、アクティブモードを使用することをお勧めします。

request.UsePassive = false;

しかし、それはクライアントとサーバーの間にファイアウォール/NATがない場合にのみ役立ちます。その場合、そもそも問題はありません(サーバーが本当に壊れていない限り、完全に間違ったIPアドレスを報告しない限り、内部1)。または、ファイアウォール/NATがインバウンド接続を許可するように構成されている場合、普通ではないもの。


別のアプローチは、サーバーによって報告された誤ったIPアドレスを無視し、プライマリ/コントロール接続IPアドレスを使用することにより、問題を回避できる別のFTPライブラリを使用することです。またはを使用して EPSV の代わりにコマンド PASV プライマリ/コントロール接続IPアドレスを暗黙的に使用するコマンド。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top