公司內部開發的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連接不到服務器,只是換了一種方式也算是一種解決辦法,沒必要在一個點上出不來。
出於網上對這個問題並沒有怎么提及,特意記錄下來。如果有道友知道確切出現問題的點還請留下你的經驗。
