在 C# 中 FTP 多个文件而无需重新建立连接

Spa*_*ott 2 .net c# ftp ftpwebrequest

FTP 协议旨在支持控制通道,并使用该控制通道告诉服务器打开 TCP 连接并传输文件。

发送或接收文件的服务器不必与 FTP 控制通道连接到的服务器相同。它可以是“三角形”类型的连接。

它还允许客户端在控制通道上登录一次,并反复告诉服务器传输文件,而无需重新登录控制通道。

显然,当他们创建 C#FtpWebRequest类时,这个概念已经完全脱离了 MS 。

我需要完全按照 FTP 协议的设计目的来做:

  1. 连接到服务器

  2. 传入凭据

  3. 创建目录(并愉快地忽略“已存在”错误)

  4. 重复传输文件到服务器

  5. 退出控制通道

我肯定没有在FtpWebRequest课堂上看到这种能力。或者任何看起来允许在 C# 代码中进行这种流程的东西。

我看过:

但这一切似乎都不允许以它应该的方式进行控制。

我可以指定KeepAlive属性,但循环必须重复调用该WebRequest.Create(targetName);函数,这将创建一个新连接,并获得一个新响应。然后它们超出范围或成为孤儿,因此根据定义,它们将被销毁。因此连接必须关闭,然后必须重新打开。对于数据连接,这没问题,但是操作 CONTROL 端口的能力在哪里?

正如 FTP 规范定义的那样,该类不允许用户区分 CONTROL 端口和 DATA 端口。

有没有办法使用 C# 类按照它的意图来执行 FTP?因为在微软狭隘的思维中,整个世界看起来就像一个 HTTP Get/Response 协议。

任何建议表示赞赏。

-斯科蒂

Mar*_*ryl 5

FtpWebRequest在连接池之上工作。所以它实际上隐式地重用了一个底层的 FTP 连接,只要FtpWebRequest.KeepAlive设置为它的默认值true

KeepAlive设置为 时true,底层 FTP(控制)连接 不会在请求完成时关闭。当您FtpWebRequest使用相同的主机、端口和用户名创建另一个实例时,将重用来自先前请求的连接。


以两个文件上传请求到同一 FTP 服务器的简单示例为例:

WebRequest request1 = WebRequest.Create("ftp://ftp.example.com/file1.zip");
request1.Credentials = new NetworkCredential("username", "password");
request1.Method = WebRequestMethods.Ftp.UploadFile;

using (Stream fileStream = File.OpenRead(@"C:\path\file1.zip"))
using (Stream ftpStream = request1.GetRequestStream())
{
    fileStream.CopyTo(ftpStream);
}

WebRequest request2 = WebRequest.Create("ftp://ftp.example.com/file2.zip");
request2.Credentials = new NetworkCredential("username", "password");
request2.Method = WebRequestMethods.Ftp.UploadFile;

using (Stream fileStream = File.OpenRead(@"C:\path\file2.zip"))
using (Stream ftpStream = request2.GetRequestStream())
{
    fileStream.CopyTo(ftpStream);
}
Run Code Online (Sandbox Code Playgroud)

如果您启用 .NET 网络日志记录,您将看到只有一个 FTP 控制连接被打开到服务器:

WebRequest request1 = WebRequest.Create("ftp://ftp.example.com/file1.zip");
request1.Credentials = new NetworkCredential("username", "password");
request1.Method = WebRequestMethods.Ftp.UploadFile;

using (Stream fileStream = File.OpenRead(@"C:\path\file1.zip"))
using (Stream ftpStream = request1.GetRequestStream())
{
    fileStream.CopyTo(ftpStream);
}

WebRequest request2 = WebRequest.Create("ftp://ftp.example.com/file2.zip");
request2.Credentials = new NetworkCredential("username", "password");
request2.Method = WebRequestMethods.Ftp.UploadFile;

using (Stream fileStream = File.OpenRead(@"C:\path\file2.zip"))
using (Stream ftpStream = request2.GetRequestStream())
{
    fileStream.CopyTo(ftpStream);
}
Run Code Online (Sandbox Code Playgroud)

请注意,这在 .NET Core 中不起作用:
使用 .NET Core 中的一个连接通过 FTP 下载多个文件