2012-04-18 50 views
2

我想連接到FTP服務器並下載文件,但我遇到了一些麻煩。爲什麼FtpWebRequest恰恰在長傳輸結束時拋出WebException?

原來我用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是==到fileSize,所以下載在技術上是完整的。 END編輯

內部異常:底層連接已關閉:接收時發生意外錯誤。

使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() 

編輯19/04/2012:我給Wireshark的ftp使用過濾器去,我可能已經發現一些更多的信息,我也不知道去哪裏...

編輯:新的信息...我發現了另一個論壇上的一些信息流出了更多的光,但仍然沒有提供答案...它看起來像文件大小沒有區別。下載一個小文件但睡眠循環中的線程以延長下載時間具有相同的效果。似乎任何長於x時間的操作(另一個職位估計爲100s)將達到結束並立即超時。我還注意到當調試器逐步完成接收到的字節總數與文件大小相等時,所以它完全像它試圖讀取文件的最後一個一樣,只發現沒有剩下的東西,除非它永遠不會發現,因爲服務器永遠不會告訴它! END EDIT

ftp服務器假設負責226 - 關閉數據連接。請求的文件操作成功(例如,文件傳輸或文件中止)。

但是,當我使用wireshark時,我可以看到這不是與它前面的[TCP重傳]進來的。還不確定這是什麼...仍然使用Google搜索。但我相信它有相關性。

所以它看起來像有些東西是超時或正在關閉,但是對於FTP都是新手,對.net有些不同,我不確定從這裏開始。

我已經嘗試了許多不同的事情:

  • 保活=假
  • SetPointManager.MaxIdleTime
  • 提高服務器超時

現在看來似乎是服務器踢我了但它與filezilla工作正常,所以必須有一些方法來避免這種情況。我試過從資源管理器下載使用資源管理器,並收到操作超時的消息。 Filezilla下載文件然後超時,但它巧妙地嘗試使用REST命令。我懷疑實施這可能是理想的解決方案,所以我想知道這一點。如果我成功了,我會作爲答覆發佈。 END EDIT

需要注意的一點是,直到WebException被傳遞時,下載文件的訪問被阻止。因此,對於WebClient而言,我無法影響超時,它會在很長一段時間內保持100%。然後拋出異常。如果我將FtpRequest超時設置爲1000,並處理異常,則該文件看起來已經完全下載,我可以在沒有任何損壞的情況下提取它。

如果有人有任何提示或指針,或甚至更好的解決方案:)我將非常感激。所有的輸入將被接受。

謝謝

P.S我試圖提供儘可能多的信息越好,但如果你需要更多的讓我知道。

+0

相關:[FTPWebRequest已損壞](http://mattmitchell.com.au/ftpwebrequest-is-broken/)。我也遇到這個問題。如果我執行'netstat',即使我立即處理響應並且'keepalive'爲'false',我也會看到數千個打開的連接。如果你在.NET的FTPWebRequest參考源中看起來好像它的目的是故意保持連接打開,希望這些端口將被重新使用,但實際上它每次都使用不同的端口... – jrh 2016-10-26 11:19:52

+0

.. 。我目前的理論是,它每次都會嘗試不同的端口,直到服務器開始拒絕連接。我編寫了一個程序,發送大量文件來測試問題。它實際上可能會用盡端口號,netstat顯示端口從49157到65535.請注意,我一次只發送一個文件。 – jrh 2016-10-26 11:35:13

回答

0

嘗試查看源應用程序配置是否限制下載的大小。

+0

如果你的意思是在app.config中?所有那裏的ATM都是跟蹤和一些設置。我閱讀了有關httpRuntime設置,但是這是FTP。有沒有類似的設置可以改變? – 2012-04-18 17:49:57

相關問題