C#实现FTP服务端和客户端

  • C#实现FTP服务端和客户端已关闭评论
  • 191 次浏览
  • A+
所属分类:.NET技术
摘要

FTP是FileTransferProtocol(文件传输协议)的英文简称,而中文简称为“文传协议”。用于Internet上的控制文件的双向传输。同时,它也是一个应用程序(Application)。基于不同的操作系统有不同的FTP应用程序,而所有这些应用程序都遵守同一种协议以传输文件。

简介

FTP是FileTransferProtocol(文件传输协议)的英文简称,而中文简称为“文传协议”。用于Internet上的控制文件的双向传输。同时,它也是一个应用程序(Application)。基于不同的操作系统有不同的FTP应用程序,而所有这些应用程序都遵守同一种协议以传输文件。

FTP客户端

系统客户端

参考文章 文件资源管理器访问ftp服务器 ,在资源管理器输入框中输入 ftp://127.0.0.1/ ,如下所示:
C#实现FTP服务端和客户端

客户端软件

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:websitevideos", @"/public_html/videos", FtpFolderSyncMode.Update);  //上载文件夹及其所有文件,并删除服务器上的其他文件 client.UploadDirectory(@"C:websiteassets", @"/public_html/assets", FtpFolderSyncMode.Mirror);  //下载文件夹及其所有文件 client.DownloadDirectory(@"C:websitelogs", @"/public_html/logs", FtpFolderSyncMode.Update);  //下载文件夹及其所有文件,并删除磁盘上的其他文件 client.DownloadDirectory(@"C:websitedailybackup", @"/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,界面如下:
C#实现FTP服务端和客户端

自定义服务端

自定义服务器使用 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.DependencyInjectionFubarDev.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));      } } 

附件