同事報案,運作多時的FTP排程忽然故障,由Log來看,問題發生在FtpWebRequest在上傳及下載資料時,持續產生"The underlying connection was closed: An unexpected error occurred on a receive."(基礎連接已關閉: 接收時發生未預期的錯誤) 錯誤。

一般來說,這類錯誤多半與FTP伺服器本身或網路環境因素有關,手動下指令FTP實測一番通常便可真相大白,正打算"手到擒來",一試之下才發現自己太天真...

就用檢測過程來說故事吧!

  1. 先手動執行一次排程程式,由Log確認目前FTP作業仍傳回失敗結果。
  2. 開cmd.exe,FTP ftpHost輸入帳號密碼,正期待彈出錯誤訊息,鎖定FTP錯誤源頭一槍斃命,沒想到登入成功、DIR也可順利取回檔案清單、最過分的是--找出排程要處理的檔案及目錄,使用PUT指令如法上傳,檔案居然也成功上傳!
  3. 改開IE,在地址列輸入ftp:// ftpHost測試,再度證實與FTP伺服器間的上傳下載管道暢通無阻。換句話說,FTP失敗只發生在使用.NET FtpWebRequest物件的程式中。
  4. 為縮小範圍,使用Mini C# Lab,把可疑的程式段落拆出來,試出可重現錯誤的最精簡程式碼:
    排版顯示純文字
    using System;
    using System.Net;
    using System.IO;
     
    public class CSharpLab
    {
        public static void Test()
        {
            string url = "ftp://ftpHost/";
            FtpWebRequest req = FtpWebRequest.Create(url) as FtpWebRequest;
            req.Credentials = new NetworkCredential("ftp", "darkthread");
            req.Method = WebRequestMethods.Ftp.ListDirectory;
            using (StreamReader sr = 
                    new StreamReader(req.GetResponse().GetResponseStream()))
            {
                Console.WriteLine(sr.ReadToEnd());
                sr.Close();
            }
        }   
    }

  5. 掌握簡單重現錯誤的方法,開始進一步測試。發現若將url換成其他FTP伺服器,不會出錯! 同樣的程式搬到其他主機執行,不會出錯! 詭異的初步結論是=>這是個只有在某台機器用FtpWebRequest連線某台FTP伺服器時才會發生的錯誤!!
  6. 出問題的機器是Windows 2000,屬於瀕臨絕種的保育類作業系統,懷疑此點特殊性或有關聯,便找了另一台Windows 2000測試,Bingo! 發生了同樣的錯誤。於是結論要修改成=>在Windows 2000上使用FtpWebRequest連線某台FTP伺服器時才會發生錯誤!!
  7. 接下來的重點是找出某台FTP伺服器到底怎麼了,一夕之間會把Windows 2000上的FtpWebRequest列為拒絕往來戶? 面對此類網路協定疑難,觀察封包應是挖掘真相最直接有效的做法,剛好測試台機器上裝有明末清初最夯的封包偵察利器--Ethereal(古董兵器配上Windows 2000真是相得應彰呀!),我就順道展現自己身為射手的博學與資深,開啟並設定Ethereal擷取發生錯誤過程的封包:
     
    (註: 以上圖例是事後驗證時的模擬資料,非偵錯過程記錄)
    由第12個封包的RST看來,在FTP Server傳回230 Response後,似乎是.NET程式端主動切斷連線的。莫非是.NET程式發生Exception導致? 同時我還注意到另一點特別之處,第9個封包的回應中出現\244\244...等文字,這才想起在早先CMD.EXE手動測試FTP時,看到FTP Server回傳了中文的歡迎訊息,當時不以為意,難道真是中文歡迎訊息搞的鬼?
  8. 找了手邊FTP Server做測試,設定中文與英文歡迎訊息再分別測試,這才真相大白。經反覆測試,證實當FTP回傳中文歡迎訊息,便會造成Windows 2000上執行的FtpWebRequest切斷連線而導致錯誤。
    以下是設定英文歡迎訊息時運作正常時的封包:

詢問了FTP的管理者,確認昨天修改過歡迎訊息,以便登入者能更明確識別自己所登入的主機,這個看似完全無害的貼心舉動,配合上Windows 2000的稀有環境及.NET FtpWebRequest元件的Bug,幾項巧合觸發今天遇到的詭異茶包。雖然我認為責任失分要記在FtpWebRequest Bug的頭上,不過Windows 2000已屬微軟不再支援的過時平台,而在XP+平台都OK,所以也不用期望積極的修正動作。在排程的Windows平台升級前,通告FTP管理同仁暫勿使用中文的FTP歡迎訊息,算是可接受的解決方案。


Comments

Be the first to post a comment

Post a comment