使用 `FtpWebRequest.GetResponse()` 連接特定 FTP 伺服器時拋出「The underlying connection was closed: The server committed a protocol violation」,但 FileZilla、WinSCP 等用戶端正常。經排查,主因在於 **伺服器回應不符合 RFC 959/2428 標準**(如多行回應格式錯誤、狀態碼異常),導致 .NET 內建 FTP 解析器拋出例外。
var req = (FtpWebRequest)WebRequest.Create($"ftp://{host}:{port}/");
req.Credentials = new NetworkCredential(user, pass);
req.Method = WebRequestMethods.Ftp.ListDirectory;
req.UseBinary = true;
req.UsePassive = true; // 關鍵嘗試
using (var resp = (FtpWebResponse)req.GetResponse()) // 這裡拋出 ProtocolViolationException
using (var reader = new StreamReader(resp.GetResponseStream()))
Console.WriteLine(reader.ReadToEnd());
.NET 配置選項允許寬鬆解析不標準 HTTP/FTP 標頭。在 `app.config` / `web.config`:
<system.net>
<settings>
<httpWebRequest useUnsafeHeaderParsing="true" />
</settings>
</system.net>
或運行時代碼(需反射,因屬性 `internal`):
var settings = typeof(System.Net.Configuration.SettingsSection).GetSection("system.net/settings");
var prop = settings.GetType().GetProperty("HttpWebRequest", BindingFlags.NonPublic | BindingFlags.Instance);
var httpSettings = prop.GetValue(settings);
var unsafeProp = httpSettings.GetType().GetProperty("UseUnsafeHeaderParsing", BindingFlags.NonPublic | BindingFlags.Instance);
unsafeProp.SetValue(httpSettings, true);
using var conn = new FtpClient(host, user, pass);
conn.Connect();
foreach (var f in conn.GetListing()) Console.WriteLine(f.Name);
若可控制 FTP 伺服器(如 vsftpd、ProFTPD、FileZilla Server、IIS FTP):
` 或 `-` 開頭,結尾 `\r\n`。 <system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.Net" maxdatasize="1024">
<listeners><add name="netlog" /></listeners>
</source>
</sources>
<sharedListeners>
<add name="netlog" type="System.Diagnostics.TextWriterTraceListener" initializeData="ftp_trace.log" />
</sharedListeners>
<switches>
<add name="System.Net" value="Verbose" />
</switches>
</system.diagnostics>