[.NET] FTP 上傳檔案時發生 System.Net.WebException: 基礎連接已關閉: 接收時發生未預期的錯誤

日前客戶IT通報有1個大型倉儲檔案(約1GB)FTP上傳2分鐘後就出現連線中斷的訊息:基礎連接已關閉: 接收時發生未預期的錯誤。

其他事證:

  • 其他較小的檔案在同一台FTP Server傳送正常。
  • 在命令提示字元下(cmd.exe)以FTP指令碼執行可以成功。

筆記這次解決方式:

1.Review FTP上傳程式碼:

 public static void Upload(string mvFtpIP, uint mvPort, bool mvUsePassive, bool mvSSL, string mvLogin, string mvPass, string mvFtpPath, string mvLocalFullFileName, string mvRemoteFileName, bool mvKeepAlive)
 {
     try
     {
         FtpWebRequest request = (FtpWebRequest)WebRequest.Create(string.Format("ftp://{0}:{1}/{2}{3}"
              , mvFtpIP
              , mvPort
              , mvFtpPath
              , mvRemoteFileName));

         request.Method = WebRequestMethods.Ftp.UploadFile;
         request.KeepAlive = mvKeepAlive;
         request.UsePassive = mvUsePassive;
         request.Credentials = new NetworkCredential(mvLogin, mvPass);
         using (Stream requestStream = request.GetRequestStream())
         {
             byte[] fileContents;
             using (FileStream sourceStream = new FileStream(mvLocalFullFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
             {
                 fileContents = new byte[sourceStream.Length];
                 sourceStream.Read(fileContents, 0, fileContents.Length);
                 requestStream.Write(fileContents, 0, fileContents.Length);
             }
         }
         using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
         {
             response.Close();
             Debug.WriteLine("Upload File Complete, status {0}", response.StatusDescription);
         }
     }
     catch (System.Exception se)
     {
         throw new System.Exception("FTP Upload Error):" + se.Message, se);
     }


 }

 

寫出的方式是1次寫入上傳Ftp server的資料流中:

requestStream.Write(fileContents, 0, fileContents.Length);

 

2.觀察FTP站台的選項:  FTP的站台預設控制通道逾時是120秒(2分鐘),感覺嫌疑很大。

但倉儲系統是UNIX系統平台,想申請改人家的設定有困難;試著自己家Try選項,分10次寫出資料流然後觀察流量看看:

for (int i = 0; i < 10; i++)
{
    if (i < 9)
    {
        requestStream.Write(fileContents, fileContents.Length / 10 * i, fileContents.Length / 10);
    }
    else
    {
        requestStream.Write(fileContents, fileContents.Length / 10 * i, fileContents.Length - (fileContents.Length / 10 * 9));
    }
}

 

驚!沒想到修改分次寫出資料流後就成功上傳了!

不太明白背後的root cause(抓頭),到底是控制通道還是資料通道逾時?

但感覺分次寫出可以通道保持聯絡(Keep in touch),筆記下來,下次繼續實驗分次次數與傳輸時間的關聯。

 

後記:

 倉儲檔案今天超過2GB,發生了System.OverflowException: 數學運算導致溢位,今晚先寫上次問題的筆記,過年再補今天筆記,來抱女兒玩飛飛去!

 

參考:

FtpWebRequest

FtpWebRequest.GetRequestStream

黑暗執行緒-FtpWebRequest奇案