34

FTP を使用してサーバーからファイルをアップロード/ダウンロードする .NET 3.5 で記述されたアプリケーションがあります。アプリは正常に動作しますが、パフォーマンスの問題があります。

  1. FTP サーバーへの接続に時間がかかります。FTP サーバーは別のネットワーク上にあり、Windows 2003 サーバー (IIS FTP) があります。アップロードのために複数のファイルがキューに入れられている場合、あるファイルから別のファイルに変更すると、FTPWebRequest を使用して新しい接続が作成され、多くの時間がかかります (約 8 ~ 10 秒)。

  2. 接続を再利用することは可能ですか? KeepAlive プロパティについてはよくわかりません。どの接続が維持され、再利用されるか。

  3. Windows Server 2003 の IIS-FTP は SSL をサポートしていないため、WireShark などのパケット スニファを介して誰でも簡単にユーザー名/パスワードを確認できます。IIS 7.0 の場合、Windows Server 2008 の新しいバージョンでは SSL over FTP がサポートされていることがわかりました。

基本的に、アプリケーションのアップロード/ダウンロードのパフォーマンスを改善したいと考えています。どんなアイデアでも大歓迎です。

** 3 は問題ではありませんが、コメントをお願いします。

4

18 に答える 18

41

次の要素を使用して、FtpWebRequest でいくつかの実験 (さまざまなサイズで約 20 個のファイルをアップロード) を行いました。

キープアライブ= true/false

ftpRequest.KeepAlive = isKeepAlive;

接続グループ名= UserDefined または null

ftpRequest.ConnectionGroupName = "MyGroupName";

接続制限= 2 (デフォルト) または 4 または 8

ftpRequest.ServicePoint.ConnectionLimit = ConnectionLimit;

モード= 同期または非同期

この例を参照してください

私の結果:

  1. ConnectionGroupName,KeepAlive=true を使用 かかった (21188.62 ミリ秒)

  2. ConnectionGroupName,KeepAlive=false を使用します (53449.00 ミリ秒)

  3. ConnectionGroupName,KeepAlive=false かかりませんでした (40335.17 ミリ秒)

  4. ConnectionGroupName,KeepAlive=true;async=true,connections=2 を使用 (11576.84 ミリ秒)

  5. ConnectionGroupName,KeepAlive=true;async=true,connections=4 を使用 (10572.56 ミリ秒)

  6. ConnectionGroupName,KeepAlive=true;async=true,connections=8 を使用 (10598.76 ミリ秒)

結論

  1. FtpWebRequest内部接続プールをサポートするように設計されています。接続プールが使用されていることを確認するには、ConnectionGroupNameが設定されていることを確認する必要があります。

  2. 接続の設定には費用がかかります。同じ資格情報を使用して同じ ftp サーバーに接続している場合、キープ アライブ フラグを true に設定すると、接続設定の数が最小限に抑えられます。

  3. ftp するファイルが多い場合は、非同期が推奨される方法です。

  4. デフォルトの接続数は 2 です。私の環境では、接続数を 4 に制限すると、全体的なパフォーマンスが最も向上します。接続数を増やしても、パフォーマンスが向上する場合と向上しない場合があります。ご使用の環境でこのパラメーターを調整できるように、構成パラメーターとして接続制限を設定することをお勧めします。

これが役に立つことを願っています。

于 2010-06-23T01:32:10.983 に答える
18

多数の接続を同時に起動できる限り、個々の接続の接続に時間がかかるかどうかは問題ではありません。転送するアイテムが多数 (たとえば数百) ある場合は、BeginGetRequestStreamBeginGetResponseなどの非同期メソッドを使用して、数十、さらには数百の WebRequest を並行して起動するのが理にかなっています。私は同様の問題 (長い接続/認証時間) に直面したプロジェクトに取り組みましたが、多くの呼び出しを並行して発行することで、全体的なスループットは実際には非常に良好でした。

また、多数 (数十、数百) のリクエストがあるとすぐに、非同期メソッドまたは同期メソッドを使用すると、大きな違いが生じます。これは、WebRequests メソッドだけでなく、アップロード/ダウンロード ストリームを取得した後に使用するストリームの読み取り/書き込みメソッドにも適用されます。Improving .Net Performance and Scalabilityの本は少し古くなっていますが、そのアドバイスの多くは今でも有効であり、オンラインで無料で読むことができます。

考慮すべきことの 1 つは、ServicePointManagerクラスが Framwework に潜んでいて、パフォーマンスを台無しにするという 1 つの唯一の目的を持っているということです。URLの ServicePoint を取得し、 ConnectionLimitを適切な値 (少なくとも意図する同時要求数と同じくらい) に変更してください。

于 2009-06-25T08:07:12.013 に答える
4

このリンクでは、ConnectionGroupName と KeepAlive の影響について説明しています: WebRequest ConnectionGroupName

于 2010-10-13T12:23:36.187 に答える
3

FTP よりも大幅に改善されたBITSをぜひチェックしてください。FTP の弱点は平文パスワードだけではありません。また、パッシブ アップロードまたはダウンロードのために開くポートを予測するという問題や、クライアントが NAT またはファイアウォールを使用している場合の全体的な問題もあります。

BITS は、IIS 拡張機能を使用して HTTP/HTTPS で動作し、低い優先度でスケジュールできるキューに入れられたアップロードとダウンロードをサポートします。クライアントとサーバーで Windows を使用している場合、FTP よりも全体的にはるかに柔軟です。

PowerShell の BITS

.NET のビット

于 2009-06-23T08:23:59.527 に答える
2

Starksoft FTP / FTPS Componentfor.NETおよびMonoを強くお勧めします。キャッシュして再利用できる接続オブジェクトがあります。

于 2010-01-15T04:34:42.513 に答える
2

個人的には、ファイルのアップロード/ダウンロードに FTP を使用するのではなく、すべてのアプリを移行し、代わりに ASP.NET の XML Web サービスに基づくソリューションを導入しました。

パフォーマンスは大幅に向上し、セキュリティはコーディングしたい程度に調整され (.NET に組み込まれているものを使用できます)、問題なく SSL を使用できます。

クライアントの接続を独自のファイアウォール経由で取得する成功率は、FTP を実行するよりもはるかに優れています。

于 2009-06-22T11:59:20.410 に答える
2

このページを見てください - http://www.ietf.org/rfc/rfc959.txt

接続を再利用できるように、接続時に別のポートを使用することを示しています。
それは動作しますか?

于 2009-06-28T19:08:01.097 に答える
1

パフォーマンスに関する問題を解決するには、次のように設定するだけです。

ftpRequest.ConnectionGroupName = "MyGroupName"; ftpRequest.KeepAlive = false; ftpRequest.ServicePoint.CloseConnectionGroup("MyGroupName");

于 2012-08-04T12:18:45.030 に答える
1

rsyncに切り替えることをお勧めします。
長所 :
転送時間を短縮するために最適化されています。
安全な転送のために SSH をサポート
TCP を使用するため、IT 部門/ファイアウォール担当者をより幸せにします

短所:
ネイティブ .NET サポートなし
Linux サーバーのインストールを対象としていますが、DeltaCopyのような適切な Windows ポートがあります。

全体としては、FTP よりもはるかに優れた選択ですが

于 2009-06-27T15:23:01.823 に答える
0

ワンポイントアドバイス:

バッファ/チャンク サイズを小さくすると、パフォーマンスが大幅に低下する

理由: より多くのディスク i/o、メモリ i/o、ftp ストリームの初期化、その他多くの要因

于 2012-02-21T10:51:03.617 に答える
0

キープアライブは機能しています。FtpWebRequest は内部に接続をキャッシュするため、しばらくしてから再利用できます。このメカニズムの詳細と説明については、ServicePointを参照してください。

別の良い情報源は、FtpWebRequest ソースを調べることです (VS2008 で実行できます)。

于 2009-06-23T08:10:31.783 に答える
0

私の知る限り、各 FtpWebRequest は、サーバーへのログオンを含め、新しい接続をセットアップする必要があります。FTP 転送を高速化したい場合は、代わりに別の FTP クライアントを使用することをお勧めします。これらの代替クライアントの一部は、ログインしてから、同じコマンド接続を使用して複数のアクションを実行できます。

このようなクライアントの例は次のとおりです: http://www.codeproject.com/KB/IP/FtpClient.aspxには、これらのライブラリが標準の FtpWebRequest およびhttp://www.codeprojectよりも高速に動作する理由についての適切な説明も含まれています。 com/KB/macros/ftp_class_library.aspxも十分に単純な実装のように見えます。

個人的には、FtpWebRequest が導入される前に、.NET 1.1 で独自の FTP 実装をロールバックしましたが、これは .NET 2.0 以降でもうまく機能します。

于 2009-06-27T15:08:04.630 に答える
0

私はそれで数日間働いていました...そして速度は本当に遅く、FileZillaと比較するものは何もありません...最終的にマルチスレッドで解決しました。ダウンロード用の接続を作成する 10 のスレッドにより、速度が向上します。標準の ftprequest 構成を使用すると、さらに改善される可能性があります。

PeticionFTP.ConnectionGroupName = "MyGroupName"
PeticionFTP.ServicePoint.ConnectionLimit = 4
PeticionFTP.ServicePoint.CloseConnectionGroup("MyGroupName")

PeticionFTP.KeepAlive = False 
PeticionFTP.UsePassive = False

PeticionFTP.UseBinary = True

PeticionFTP.Credentials = New NetworkCredential(lHost.User, lHost.Password)
于 2015-09-27T20:49:22.887 に答える
-1

以下のコードを試してください。パフォーマンスが向上します。

private void Upload144_Click(object sender, EventArgs e)
{
    OpenFileDialog fileobj = new OpenFileDialog();
    fileobj.InitialDirectory = "C:\\";
    //fileobj.Filter = "Video files (*.mp4)";
    //fileobj.ShowDialog();

    if (fileobj.ShowDialog() == DialogResult.OK)
    {
        if (fileobj.CheckFileExists)
        {
            string test = Properties.Settings.Default.Connection;
            SqlConnection con = new SqlConnection(test);
            con.Open();
            string correctfilename = System.IO.Path.GetFileName(fileobj.FileName);
            SqlCommand cmd = new SqlCommand("Insert into Path(ID,Path5) VALUES   ((select isnull(MAX(id),0) + 1 from Path),'\\Videos\\" + correctfilename + "')", con);

            cmd.ExecuteNonQuery();

            string path = Application.StartupPath.Substring(0, Application.StartupPath.Length - 10);
            con.Close();

            //For Progressbar
            DataTable dt = new DataTable();
       //   SqlDataAdapter da = new SqlDataAdapter(cmd);
       //   da.Fill(dt);

            timer5.Enabled = true;

            // FOR FtpServer File Upload::
            string uploadfile = fileobj.FileName;
            string uploadFileName = new FileInfo(uploadfile).Name;

            string uploadUrl = "ftp://ftp.infotech.com/";
            FileStream fs = new FileStream(uploadfile, FileMode.Open, FileAccess.Read);
            try
            {
                long FileSize = new FileInfo(uploadfile).Length; // File size of file being uploaded.
                Byte[] buffer = new Byte[FileSize];

                fs.Read(buffer, 0, buffer.Length);

                fs.Close();
                fs = null;
                string ftpUrl = string.Format("{0}/{1}", uploadUrl, uploadFileName);
                FtpWebRequest requestObj = FtpWebRequest.Create(ftpUrl) as FtpWebRequest;
                requestObj.Method = WebRequestMethods.Ftp.UploadFile;
                requestObj.Credentials = new NetworkCredential("test@sample.com", "test@123");
                Stream requestStream = requestObj.GetRequestStream();
                requestStream.Write(buffer, 0, buffer.Length);

                requestStream.Flush();
                requestObj = null;
            }
            catch (Exception ex)
            {
                //MessageBox.Show("File upload/transfer Failed.\r\nError Message:\r\n" + ex.Message, "Succeeded", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
    }
}
于 2016-02-15T12:09:39.103 に答える