FTP サーバーに接続してファイルをダウンロードしようとしていますが、問題が発生しています。
もともと私は WebClient.DownloadFileAsync を使用していましたが、小さなファイルでは問題なく動作しましたが、大きなファイルはダウンロードの最後に到達しましたが、DownloadFileCompleted を呼び出すことはありませんでした...
FtpWebRequest に切り替え、FileStream を使用して標準的な方法でファイルを書き込もうとしました。
var FtpRequest = WebRequest.Create(uri) as FtpWebRequest
FtpRequest.Credentials = _Credentials;
FtpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
using(var InputResponse = (FtpWebResponse)FtpRequest.GetResponse())
using (var InputStream = InputResponse.GetResponseStream())
using (var OutputStream = new FileStream(_DownloadDirectory + "\\" + fileName, FileMode.Create))
{
var Buffer = new byte[1024];
int TotalReadBytesCount = 0;
int ReadBytesCount;
while ((ReadBytesCount = InputStream.Read(Buffer, 0, Buffer.Length)) > 0)
{
OutputStream.Write(Buffer, 0, ReadBytesCount);
TotalReadBytesCount += ReadBytesCount;
var Progress = (int)(((double)TotalReadBytesCount / (double)FileSize) * 100);
UpdateProgressBar(progressBar, Progress);
}
}
これも小さなファイルでは問題なく動作しますが、大きなファイルではファイル全体をダウンロードしてから、InputStream.Read で System.Net.WebException を取得します。
編集:コードの構造に応じて例外が移動します...「使用中」のステートメントを削除し、各ストリームと応答を閉じると、最後の x.close() によって例外がスローされます。また、TotalBytesReceived は == to fileSize であるため、ダウンロードは技術的に完了していることに注意してください。編集終了
内部例外: 基になる接続が閉じられました: 受信時に予期しないエラーが発生しました。
system.Net.Tracing を有効にした後、次のログファイルを取得しました。
System.Net Verbose: 0 : [2440] WebRequest::Create(ftp://ftp.******.com/)
System.Net Information: 0 : [2440] FtpWebRequest#63621045::.ctor(ftp://ftp.******.com/)
System.Net Verbose: 0 : [2440] Exiting WebRequest::Create() -> FtpWebRequest#63621045
System.Net Verbose: 0 : [2440] FtpWebRequest#63621045::GetResponse()
System.Net Information: 0 : [2440] FtpWebRequest#63621045::GetResponse(Method=SIZE.)
System.Net Information: 0 : [2440] FtpControlStream#44374744 - Created connection from ***.**.***.**:***** to **.**.**.**:**.
System.Net Information: 0 : [2440] Associating FtpWebRequest#63621045 with FtpControlStream#44374744
System.Net Information: 0 : [2440] FtpControlStream#44374744 - Received response [220 Microsoft FTP Service]
System.Net Information: 0 : [2440] FtpControlStream#44374744 - Sending command [USER ******]
System.Net Information: 0 : [2440] FtpControlStream#44374744 - Received response [331 Password required for cashipftp.]
System.Net Information: 0 : [2440] FtpControlStream#44374744 - Sending command [PASS ********]
System.Net Information: 0 : [2440] FtpControlStream#44374744 - Received response [230 User logged in.]
System.Net Information: 0 : [2440] FtpControlStream#44374744 - Sending command [OPTS utf8 on]
System.Net Information: 0 : [2440] FtpControlStream#44374744 - Received response [200 OPTS UTF8 command successful - UTF8 encoding now ON.]
System.Net Information: 0 : [2440] FtpControlStream#44374744 - Sending command [PWD]
System.Net Information: 0 : [2440] FtpControlStream#44374744 - Received response [257 "/" is current directory.]
System.Net Information: 0 : [2440] FtpControlStream#44374744 - Sending command [SIZE Superintendents/MSK/Stock Keeper_be.zip]
System.Net Information: 0 : [2440] FtpControlStream#44374744 - Received response [213 96601015]
System.Net Information: 0 : [2440] FtpControlStream#44374744 - Sending command [QUIT]
System.Net Information: 0 : [2440] FtpControlStream#44374744 - Received response [221 Goodbye.]
System.Net Information: 0 : [2440] FtpWebRequest#63621045::(Releasing FTP connection#44374744.)
System.Net Verbose: 0 : [2440] Exiting FtpWebRequest#63621045::GetResponse()
System.Net Verbose: 0 : [2440] FtpWebResponse#50706457::Close()
System.Net Verbose: 0 : [2440] Exiting FtpWebResponse#50706457::Close()
System.Net Verbose: 0 : [2440] WebRequest::Create(ftp://ftp.******.com/)
System.Net Information: 0 : [2440] FtpWebRequest#89223::.ctor(ftp://ftp.*****.com/)
System.Net Verbose: 0 : [2440] Exiting WebRequest::Create() -> FtpWebRequest#89223
System.Net Verbose: 0 : [2440] FtpWebRequest#89223::GetResponse()
System.Net Information: 0 : [2440] FtpWebRequest#89223::GetResponse(Method=RETR.)
System.Net Information: 0 : [2440] FtpControlStream#4015056 - Created connection from ***.**.***.**:***** to **.**.**.**:**.
System.Net Information: 0 : [2440] Associating FtpWebRequest#89223 with FtpControlStream#4015056
System.Net Information: 0 : [2440] FtpControlStream#4015056 - Received response [220 Microsoft FTP Service]
System.Net Information: 0 : [2440] FtpControlStream#4015056 - Sending command [USER ******]
System.Net Information: 0 : [2440] FtpControlStream#4015056 - Received response [331 Password required for cashipftp.]
System.Net Information: 0 : [2440] FtpControlStream#4015056 - Sending command [PASS ********]
System.Net Information: 0 : [2440] FtpControlStream#4015056 - Received response [230 User logged in.]
System.Net Information: 0 : [2440] FtpControlStream#4015056 - Sending command [OPTS utf8 on]
System.Net Information: 0 : [2440] FtpControlStream#4015056 - Received response [200 OPTS UTF8 command successful - UTF8 encoding now ON.]
System.Net Information: 0 : [2440] FtpControlStream#4015056 - Sending command [PWD]
System.Net Information: 0 : [2440] FtpControlStream#4015056 - Received response [257 "/" is current directory.]
System.Net Information: 0 : [2440] FtpControlStream#4015056 - Sending command [TYPE I]
System.Net Information: 0 : [2440] FtpControlStream#4015056 - Received response [200 Type set to I.]
System.Net Information: 0 : [2440] FtpControlStream#4015056 - Sending command [PASV]
System.Net Information: 0 : [2440] FtpControlStream#4015056 - Received response [227 Entering Passive Mode (77,44,60,82,106,69).]
System.Net Information: 0 : [2440] FtpControlStream#4015056 - Sending command [RETR *****]
System.Net Information: 0 : [2440] FtpControlStream#4015056 - Received response [125 Data connection already open; Transfer starting.]
System.Net Verbose: 0 : [2440] Exiting FtpWebRequest#89223::GetResponse()
System.Net Information: 0 : [1312] ServicePoint#42865679 - Closed as idle.
System.Net.Sockets Error: 0 : [2440] Socket#10316078::UpdateStatusAfterSocketError() - TimedOut
System.Net.Sockets Error: 0 : [2440] Exception in Socket#10316078::Receive - A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
System.Net Information: 0 : [2440] FtpWebRequest#89223::(Releasing FTP connection#4015056.)
System.Net Verbose: 0 : [2440] FtpWebResponse#19201658::Close()
System.Net Verbose: 0 : [2440] Exiting FtpWebResponse#19201658::Close()
EDIT 19/04/2012: 私は Wireshark に ftp フィルターを使用してみました。
編集:新しい情報...別のフォーラムで、もう少し光を当てるが、まだ答えを提供していない情報を見つけました...ファイルサイズに違いはないようです。小さなファイルをダウンロードするが、ループ内でスレッドをスリープさせてダウンロード時間を延長することは、同じ効果があります。x時間(他の投稿では100秒と見なされます)より長い操作はすべて終了し、すぐにタイムアウトするようです。また、デバッガーをステップスルーするときに、受信したバイトの合計がファイルサイズに等しいことに注意しました。そのため、サーバーが決して見つからないことを除いて、ファイルの最後を読み取ろうとするのとまったく同じです。それを言う!編集終了
ftp サーバーは 226 - Closing data connection で応答すると想定されています。要求されたファイル アクションが成功しました (たとえば、ファイル転送またはファイルの中止)。
ただし、wireshark を使用すると、[TCP 再送信] が前に付いていないことがわかります。これが何であるかはまだわかりません...まだグーグルです。しかし、私はそれが関連性を持っていると確信しています。
そのため、何かがタイムアウトしているか、早期に閉じられているように見えますが、FTP と .net の両方が初めてなので、ここからどこに進むべきかわかりません。
私はさまざまなことを試しました:
- キープアライブ = false
- SetPointManager.MaxIdleTime
- サーバータイムアウトの増加
サーバーが私を追い出しているようですが、filezillaでは問題なく動作するため、これを回避する方法が必要です。
EDIT 20/04/2012: filezilla (またはエクスプローラー) では正常に動作しません エクスプローラーを使用して ftp からダウンロードしようとしたところ、操作がタイムアウトしたというメッセージが表示されました。Filezilla はファイルをダウンロードしてからタイムアウトしますが、巧妙に REST コマンドで再試行します。これを実装することが理想的なソリューションであると思われるので、それを理解するために出発します。成功したら回答として投稿します。編集終了
注意すべき点の 1 つは、WebException が渡されるまで、ダウンロードしたファイルへのアクセスがブロックされることです。したがって、タイムアウトに影響を与えることができない WebClient の場合、長時間 100% でハングアップします。そして例外をスローします。FtpRequest タイムアウトを 1000 に設定して例外を処理すると、ファイルは完全にダウンロードされたように見え、破損することなく抽出できます。
誰かがヒントや指針、またはさらに良い解決策を持っている場合:)私は非常に感謝しています. すべての入力が受け入れられます。
ありがとうございました
PSできるだけ多くの情報を提供しようとしましたが、さらに必要な場合はお知らせください。