簡介 FTP是FileTransferProtocol(文件傳輸協議)的英文簡稱,而中文簡稱為“文傳協議”。用於Internet上的控制文件的雙向傳輸。同時,它也是一個應用程式(Application)。基於不同的操作系統有不同的FTP應用程式,而所有這些應用程式都遵守同一種協議以傳輸文件。 FTP ...
目錄
簡介
FTP是FileTransferProtocol(文件傳輸協議)的英文簡稱,而中文簡稱為“文傳協議”。用於Internet上的控制文件的雙向傳輸。同時,它也是一個應用程式(Application)。基於不同的操作系統有不同的FTP應用程式,而所有這些應用程式都遵守同一種協議以傳輸文件。
FTP客戶端
系統客戶端
參考文章 文件資源管理器訪問ftp伺服器 ,在資源管理器輸入框中輸入 ftp://127.0.0.1/ ,如下所示:
客戶端軟體
WinSCP 是一個流行的 SFTP 客戶端和 Microsoft Windows 的 FTP 客戶端!使用在本地電腦和遠程伺服器之間複製文件FTP、FTPS、SCP、SFTP、WebDAV 或 S3 文件傳輸協議。
官網:https://winscp.net/eng/index.php
github:https://github.com/winscp/winscp
WinSCP也支持C#調用,參考 WinSCP .NET 程式集和 COM 庫。
自定義客戶端
自定義客戶端使用 FluentFTP 庫,代碼如下:
//創建FTP客戶端並指定主機、用戶名和密碼(刪除憑據以使用“匿名”帳戶)
FtpClient client = new FtpClient("123.123.123.123", "david", "pass123");
//連接到伺服器並自動檢測工作FTP設置
client.AutoConnect();
//獲取“/htdocs”文件夾中的文件和目錄列表
foreach (FtpListItem item in client.GetListing("/htdocs"))
{
//如果這是一個文件
if (item.Type == FtpFileSystemObjectType.File)
{
//獲取文件大小
long size = client.GetFileSize(item.FullName);
//計算伺服器端文件的哈希值(預設演算法)
FtpHash hash = client.GetChecksum(item.FullName);
}
//獲取文件或文件夾的修改日期/時間
DateTime time = client.GetModifiedTime(item.FullName);
}
//上傳文件
client.UploadFile(@"C:\MyVideo.mp4", "/htdocs/MyVideo.mp4");
//移動上傳的文件
client.MoveFile("/htdocs/MyVideo.mp4", "/htdocs/MyVideo_2.mp4");
//再次下載文件
client.DownloadFile(@"C:\MyVideo_2.mp4", "/htdocs/MyVideo_2.mp4");
//將下載的文件與伺服器進行比較
if (client.CompareFile(@"C:\MyVideo_2.mp4", "/htdocs/MyVideo_2.mp4") == FtpCompareResult.Equal) { }
//刪除文件
client.DeleteFile("/htdocs/MyVideo_2.mp4");
//上傳文件夾及其所有文件
client.UploadDirectory(@"C:\website\videos\", @"/public_html/videos", FtpFolderSyncMode.Update);
//上傳文件夾及其所有文件,並刪除伺服器上的其他文件
client.UploadDirectory(@"C:\website\assets\", @"/public_html/assets", FtpFolderSyncMode.Mirror);
//下載文件夾及其所有文件
client.DownloadDirectory(@"C:\website\logs\", @"/public_html/logs", FtpFolderSyncMode.Update);
//下載文件夾及其所有文件,並刪除磁碟上的其他文件
client.DownloadDirectory(@"C:\website\dailybackup\", @"/public_html/", FtpFolderSyncMode.Mirror);
//遞歸刪除文件夾
client.DeleteDirectory("/htdocs/extras/");
//檢查文件是否存在
if (client.FileExists("/htdocs/big2.txt")) { }
//檢查文件夾是否存在
if (client.DirectoryExists("/htdocs/extras/")) { }
//上傳文件並重試3次,然後放棄
client.RetryAttempts = 3;
client.UploadFile(@"C:\MyVideo.mp4", "/htdocs/big.txt", FtpRemoteExists.Overwrite, false, FtpVerify.Retry);
//斷開再見!
client.Disconnect();
FTP服務端
系統服務端
參考 Win10--開啟FTP的方法、Windows10上怎樣開啟FTP服務:
- 啟用FTP和IIS
- 添加FTP站點
- 設置身份驗證
- 設置防火牆
服務端軟體
FTP服務端軟體推薦使用Quick Easy FTP Server V4.0.0,界面如下:
自定義服務端
自定義伺服器使用 FubarDev.FtpServer 庫,代碼如下
// 設置依賴項註入
var services = new ServiceCollection();
// 使用%TEMP%/TestFtpServer作為根文件夾
services.Configure<DotNetFileSystemOptions>(opt => opt
.RootPath = Path.Combine(Path.GetTempPath(), "TestFtpServer"));
// 添加FTP伺服器服務
// DotNetFileSystemProvider = 使用.NET文件系統功能
// AnonymousMembershipProvider = 僅允許匿名登錄
services.AddFtpServer(builder =>
{
builder.UseDotNetFileSystem(); // 使用.NET文件系統功能
builder.EnableAnonymousAuthentication();// 允許匿名登錄
/builder.Services.AddSingleton<IMembershipProvider, TestMembershipProvider>();//用戶登錄
} );
// 配置FTP伺服器
services.Configure<FtpServerOptions>(opt => opt.ServerAddress = "127.0.0.1");
// 構建服務提供商
using (var serviceProvider = services.BuildServiceProvider())
{
// 初始化FTP伺服器
var ftpServerHost = serviceProvider.GetRequiredService<IFtpServerHost>();
// 啟動FTP伺服器
ftpServerHost.StartAsync(CancellationToken.None).Wait();
Console.WriteLine("Press ENTER/RETURN to close the test application.");
Console.ReadLine();
// 停止FTP伺服器
ftpServerHost.StopAsync(CancellationToken.None).Wait();
}
需要先安裝 Microsoft.Extensions.DependencyInjection 和 FubarDev.FtpServer.FileSystem.DotNet,完整的創建過程如下:
dotnet new console
dotnet add package FubarDev.FtpServer.FileSystem.DotNet
dotnet add package FubarDev.FtpServer
dotnet add package Microsoft.Extensions.DependencyInjection
官方的示例只有匿名登錄,如果想使用用戶校驗,需要自己實現IMembershipProvider介面,代碼如下:
public class TestMembershipProvider : IMembershipProvider
{
public Task<MemberValidationResult> ValidateUserAsync(string username, string password)
{
if (username == "admin" && password == "admin")
{
var identity = new ClaimsIdentity();
identity.AddClaim(new Claim(ClaimTypes.Name, username));
identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
return Task.FromResult(new MemberValidationResult(MemberValidationStatus.AuthenticatedUser, new ClaimsPrincipal(identity)));
}
return Task.FromResult(new MemberValidationResult(MemberValidationStatus.InvalidLogin));
}
}