公司內部開發的winform程序使用了FtpWebRequest下載FTP服務器的文件到本地。
大多數人運行良好,由於我們是試運行逐步有人加入到平台的使用,前兩天突然有個別機器無法連接FTP服務器報出了如下錯誤。
The underlying connection was closed:The connection was closed unexpectedly
進行排查沒有發現異常,windows事件管理器中查看也沒有相關的錯誤。寫的代碼也沒有發現什么不對的地方
FtpWebRequest reqFtp = (FtpWebRequest)FtpWebRequest.Create(new Uri(url)); reqFtp.UseBinary = true; reqFtp.Credentials = new NetworkCredential(FTPUSERNAME, FTPPASSWORD); FtpWebResponse response = (FtpWebResponse)reqFtp.GetResponse(); Stream ftpStream = response.GetResponseStream(); int bufferSize = 2048; int readCount; byte[] buffer = new byte[bufferSize]; readCount = ftpStream.Read(buffer, 0, bufferSize); FileStream outputStream = new FileStream(newFileName, FileMode.Create); while (readCount > 0) { outputStream.Write(buffer, 0, readCount); readCount = ftpStream.Read(buffer, 0, bufferSize); } ftpStream.Close(); outputStream.Close(); response.Close();
一時之間比較懵逼,同時網上搜索FtpWebRequest "基礎連接被關閉,連接被意外關閉" 的異常更是少之又少。估計這年頭大家都不怎么開發桌面程序,所以用到這個類的出現問題的更少。
但是說實話寫了winform程序的人或許對多線程,事件委托,網絡請求,Windows服務等技術會有更深的理解。
無奈沒有現成的解決方案,加上99%的人運行程序正常,最后懷疑是機器環境問題。由於工作比較忙就直接喊運維給他重新裝了系統(這個方法不推薦,我們情況比較特殊)。
通過重裝后就能正常下載文件了,但是又過了2天,這位同學的機器又無法下載了(這部分同學對電腦不是很熟悉,解壓軟件有時候都不知道裝)。不知道是操作了什么還是殺毒軟件誤殺。
最后本着不能讓別人再裝系統吧,得找一下是不是自己程序得問題。
測試+搜索依然毫無進展,然后我就去官方文檔看了下,直到我發現這個東西:
然后進入GitHub
stack overflow上面的關於這個第三方庫的問答。
最后重新改寫下載代碼,使用 nuget 添加FluentFTP類庫
using (FtpClient conn = new FtpClient()) { conn.Host = uri.Host; conn.Port = uri.Port; conn.Credentials = new NetworkCredential(FTPUSERNAME, FTPPASSWORD); byte[] outBuffs; bool flag = conn.Download(out outBuffs, uri.AbsolutePath); FileStream fs = new FileStream(newFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); fs.Write(outBuffs, 0, outBuffs.Length); //清空緩沖區、關閉流 fs.Flush(); fs.Close(); }
最后更新程序后一切都風平浪靜了!
其實這個問題不應該是FtpWebRequest的問題,因為這個類是依賴.net Framework的,應該是部分機器環境問題導致可能出現未知的網絡問題。換用FluentFTP只是換了一個第三方庫,在打包程序的時候被一起打包了。所以以后再操作這種網絡請求的時候還是盡量用第三方庫吧,畢竟每個機器環境我們無法排查(程序員會修電腦?)。
最后說下HttpWebRequest也存在同樣的各種意想不到的問題,建議大家用 RestSharp 這個庫。其實通篇下來並沒有找到具體是什么導致FtpWebRequest連接不到服務器,只是換了一種方式也算是一種解決辦法,沒必要在一個點上出不來。
出於網上對這個問題並沒有怎么提及,特意記錄下來。如果有道友知道確切出現問題的點還請留下你的經驗。