早上接獲通報,一台主機的例行FTP作業失敗,檔案沒有正確上傳到Windows 2000的FTP Server。這個排程已經運作好長一段時間了,倒是第一次遇到此種狀況。

我先由FTP Log查起,看到了以下的記錄:
00:55:02 192.168.1.5 [62]USER anonymous 331
00:55:02 192.168.1.5 [62]PASS foo@boo.com 230
00:56:22 192.168.1.5 [62]created TheData.csv 426

查了一下,FTP Status Code 426 = Connection closed; transfer aborted. The command opens a data connection to perform an action, but that action is canceled, and the data connection is closed.。

(此時有段插曲,由於排程上傳失敗,同事重跑上傳作業,確認在FTP Server上有看到上傳檔案,有抓圖畫面為證;但待我檢查時,檔案卻不見蹤影)

我改以全手工上傳檔案,發現上傳這個707KB的檔案時,FTP Client會Hang住,一陣子後再彈出Netout :Connection reset by peer的錯誤訊息。有意思的是,在Hang住的期間,Server端可以看到並下載該檔案,上傳端收到錯誤後,檔案又彷彿被Rollback一般消失無蹤。(Dirty Read?) 這解釋了前述的插曲。

再做了一些測試,發現只有在上傳大檔案時會出錯。為了明確抓出會出錯的檔案大小,我用Mini C# Lab產生了一連串大小不同的txt檔案(這也算Mini C# Lab的經典應用情境),分別上傳測試,最後找出上傳703KB成功,704KB檔案失敗的臨界點,而今天早上失敗的上傳檔大小剛好是707KB。

D:\TEMP>ftp 192.168.1.9
Connected to 192.168.1.9.
220 MyFtp Microsoft FTP Service (Version 5.0).
User (192.168.1.9:(none)): ftp
331 Anonymous access allowed, send identity (e-mail name) as password.
Password:
230 Anonymous user logged in.
ftp> put data701.txt
200 PORT command successful.
150 Opening ASCII mode data connection for DATA701.txt.
226 Transfer complete.
ftp: 717824 bytes sent in 0.75Seconds 957.10Kbytes/sec.
ftp> put data702.txt
200 PORT command successful.
150 Opening ASCII mode data connection for DATA702.txt.
226 Transfer complete.
ftp: 718848 bytes sent in 0.70Seconds 1021.09Kbytes/sec.
ftp> put data703.txt
200 PORT command successful.
150 Opening ASCII mode data connection for DATA703.txt.
226 Transfer complete.
ftp: 719872 bytes sent in 0.69Seconds 1047.85Kbytes/sec.

ftp> put data704.txt
200 PORT command successful.
150 Opening ASCII mode data connection for DATA704.txt.
> Netout :Connection reset by peer
Connection closed by remote host.
ftp>

再深入Google了一下,發現比較可能的狀況是網路傳輸時TCP/IP時Window Size(Buffer)不足,雖然這種情況比較常發生於網路頻寬不足(本案中兩台機器在同一個LAN,FTP實測也有1MB/sec的水準)或Server端接收資料不及(本案中FTP Server CPU %幾乎永遠躺平),與我的實際情況並不相符,但我還是試了ftp -w:16384 192.168.1.9,將Window Size由預設4096放大四倍後,上傳超過704KB的檔案就也不再發生問題。

由此,應可推論本次的FTP連線錯誤是因為Window Size不足引起,但導致Windows Size不足的原因仍然是謎。我試了其他台的Windows 2000 FTP Server無此問題,查了問題FTP Server的Log,過去一年來也只零星發生不到十次426 Error;在有時間挖掘出真相前,我建議開發人員FTP配合加上Window Size參數因應這台古怪的機器。


Comments

# by eric

謝謝 Jeffrey 我前2天也遇到相同的問題,一直找不到為什麼 看到這篇文章終於給我帶來一線生機(我承認有點跨張啦) 不過我用的備份軟體並沒有可以讓我修改Windows Size 的地方. 突然想起來 windows 本身也有類似的參數, 用 Tcp Opeimiter 這個軟體調整一下TCP Receive window . 今天淩晨的備份已經正常了.連備份速度都變快了. 小小心得分享一下.

# by learn

你好, 最近剛在學習程式 對於能"產生了一連串大小不同的txt檔案" 感到好奇 不知道應如何實現 可以給我一個方向嗎?! 謝謝您!

# by Jeffrey

to learn, 我用的方法是FileStream.Seek到特定長度, 再WriteByte(0) http://msdn.microsoft.com/en-us/library/system.io.filestream.seek.aspx 以下例子建立一個1024*1024 1MB大小的檔案 FileStream fs = new FileStream(@"C:\Temp\F1.txt", FileMode.Create); fs.Seek(1024 * 1024 - 1, SeekOrigin.Begin); fs.WriteByte(0); fs.Close();

# by learn

謝謝您的回覆!

# by Jacky

我每天排程用FTP好幾年了, 上個禮拜開始出現 Netout :Connection reset by peer 在FTP 命令後面加了參數 -w:16384, 結果真的正常了. 非常感謝!

Post a comment