本文提供一個功能完整的 FTPClient 類別,封裝連線、登入、檔案上傳下載、目錄管理、重命名、刪除等操作,採用 Socket 直接實作 FTP 協定(主動/被動模式),適合深入理解 FTP 流程或無法使用 FtpWebRequest 的環境。
Put)、下載 (Get)、批次操作MkDir)、刪除 (RmDir)、切換 (ChDir)FTPClient ftp = new FTPClient();
ftp.RemoteHost = "ftp.example.com";
ftp.RemoteUser = "user";
ftp.RemotePass = "pass";
ftp.RemotePath = "/public";
ftp.RemotePort = 21;
try
{
ftp.Connect();
// 下載單一檔案
ftp.Get("remote.txt", @"C:\Local\", "local.txt");
// 上傳檔案
ftp.Put(@"C:\Local\upload.txt");
ftp.DisConnect();
}
catch (Exception ex)
{
MessageBox.Show($"FTP 錯誤: {ex.Message}");
}
// 建立被動模式資料 Socket
private Socket CreateDataSocket()
{
SendCommand("PASV");
if (iReplyCode != 227) throw new IOException(strReply.Substring(4));
// 解析回應中的 IP 與 Port
int idx1 = strReply.IndexOf('(');
int idx2 = strReply.IndexOf(')');
string[] parts = strReply.Substring(idx1 + 1, idx2 - idx1 - 1).Split(',');
string ip = $"{parts[0]}.{parts[1]}.{parts[2]}.{parts[3]}";
int port = (int.Parse(parts[4]) << 8) + int.Parse(parts[5]);
Socket dataSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
dataSocket.Connect(new IPEndPoint(IPAddress.Parse(ip), port));
return dataSocket;
}
// 下載檔案核心邏輯
public void Get(string remoteFile, string localFolder, string localFileName)
{
SetTransferType(TransferType.Binary);
using (FileStream fs = new FileStream(Path.Combine(localFolder, localFileName), FileMode.Create))
using (Socket dataSocket = CreateDataSocket())
{
SendCommand($"RETR {remoteFile}");
// 檢查回應碼 150/125/226/250
byte[] buffer = new byte[512];
int bytesRead;
while ((bytesRead = dataSocket.Receive(buffer)) > 0)
fs.Write(buffer, 0, bytesRead);
}
}
現代替代方案: .NET 內建 FtpWebRequest 或第三方函式庫 FluentFTP 提供更高層抽象。