Code Bye

C# FTP 大批量下載(1kb~50M) 異常 ,求指導

3個異常問題:
1.The underlying connection was closed: An unexpected error occurred on a receive.
2.Unable to read data from the transport connection: 連線嘗試失敗,因為連線對象有一段時間並未正確回應,或是連線建立失敗,因為連線的主機無法回應。
3.Unable to read data from the transport connection: 遠端主機已強制關閉一個現存的連線。
三個異常都是  readCount = ftpStream.Read(buffer, 0, bufferSize);這段代碼報錯的,下載同一文件可能會出現上面的異常也有可能不會出現,
第三點(: 遠端主機已強制關閉一個現存的連線)微軟有解釋https://support.microsoft.com/zh-tw/kb/931130,微軟的解釋不太明白,修改註冊表不可取
徵狀
當您使用 FTP 用戶端從 FTP 伺服器下載大型檔案時,您會收到類似下列的錯誤訊息︰
遠端主機已關閉的連線
假如下列情況成立,就會發生這個問題︰
應用程式層閘道服務正在執行 FTP 伺服器上。
路由及遠端存取服務正在執行 FTP 伺服器上。
方法 1
假如您不需要使用服務,請停止應用程式層閘道服務。
方法 2
警告假如您修改登錄不當使用 「 登錄編輯器,或使用另一種方法,可能會發生嚴重的問題。這些問題可能會要求您重新安裝作業系統。Microsoft 不保證可以解決這些問題。修改登錄請自行承擔風險。
變更要影響的 FTP 伺服器上的應用程式層閘道服務行為的登錄值。若要執行這項操作,請參考下列步驟:
按一下 [開始],按一下 [執行]、 輸入Regedit,然後按一下[確定]。
找出並按一下下列登錄子機碼︰
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ALG\ISV\{6E590D61-F6BC-4dad-AC21-7DC40D304059}
在 [結果] 窗格中,按兩下 [ PreferExternalManifest]。
在 [數值資料] 方塊中,鍵入停用,,然後按一下[確定]。
在 [檔案] 功能表上按一下 [結束] 以關閉 [登錄編輯程式]。
變更登錄值之後,應用程式層閘道服務並不會讓 FTP 伺服器的連接埠對應。
代碼段:
private void Connect(string ServerURL)
{
try
{
FTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ServerURL));
FTP.UseBinary = true;
FTP.Credentials = new NetworkCredential(_LoginUser, _PassWord);
//關閉被動模式
FTP.UsePassive = false;//設置為true,可能會出現The remote server returned an error: 227 Entering Passive Mode

}
catch (System.Exception ex)
{
PubFile.WriteLog(“Connect”, ex.Message, “連接失敗”+ServerURL);
}
}
public string DownloadFile(string subPath, string LocalPath, string FileName)
{
string ErrorInfo = “”;
string ServerURL = “FTP://” + _ServerName + “/” + _VDir + “/” + subPath + “/” + FileName;
Stream ftpStream = null;
FileStream outputStream = null;
try
{
string FullFilePath = Path.Combine(LocalPath, FileName);
Connect(ServerURL);
//FTP.Timeout = 180000;
FTP.KeepAlive = false;//完成下載立即斷開文件
FTP.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse response = (FtpWebResponse)FTP.GetResponse();
ftpStream = response.GetResponseStream();
ftpStream.ReadTimeout = 30000;//半分鐘讀不到數據超時
//int bufferSize = 2048;
int bufferSize = 1024 * 8;
int readCount;
byte[] buffer = new byte[bufferSize];
#region =======開始下載====================
readCount = ftpStream.Read(buffer, 0, bufferSize);
outputStream = new FileStream(FullFilePath, FileMode.Create);
int i = 1;
while (readCount > 0)
{
outputStream.Write(buffer, 0, readCount);
//觸發下載事件
if (FileDownLoadEvent != null)
{
FileDownLoadEvent(i * bufferSize);//kb
i++;
}
readCount = ftpStream.Read(buffer, 0, bufferSize);
}
#endregion =======開始下載====================
}
catch (System.Exception ex)
{
ErrorInfo = ex.Message;
PubFile.WriteLog(“DownloadFile”, ex.Message, ServerURL);
}
finally
{
if (ftpStream != null)
{

ftpStream.Flush();
ftpStream.Dispose();
ftpStream.Close();
}
if (outputStream != null)
{
outputStream.Flush();
outputStream.Dispose();
outputStream.Close();
}
}
return ErrorInfo;
}

解决方案

40

可以把那2个timeout设置的长一点

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明C# FTP 大批量下載(1kb~50M) 異常 ,求指導