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

时间:2018-02-27 15:13:51

标签: c# .net ftp ftpwebrequest multiple-files

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

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

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

显然,这个概念在创建C#FtpWebRequest类时已完全逃脱了MS。

我需要完成FTP协议的设计目的:

  1. 连接服务器

  2. 传递凭据

  3. 创建目录(并乐意忽略“已存在'错误”)

  4. 反复将文件传输到服务器

  5. 退出控制频道

  6. 我确定在FtpWebRequest课程中没有看到这种能力。或任何看似允许C#代码中的那种流的东西。

    我看过了:

    但这似乎都没有让控制方式符合原样。

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

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

    有没有办法使用C#类按原来的方式进行FTP?因为在微软的狭隘思维模式中,整个世界看起来像是一个HTTP Get / Response协议。

    感谢任何建议。

    -Scotty

2 个答案:

答案 0 :(得分:1)

FtpWebRequest在连接池之上工作。因此,只要FtpWebRequest.KeepAlive设置为默认值true就会隐式重用基础FTP连接。

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);
}

如果您enable .NET network logging,您将看到只有一个FTP控制连接被打开到服务器:

FtpWebRequest#45004109::.ctor(ftp://ftp.example.com/file1.zip)
FtpWebRequest#45004109::GetRequestStream(Method=STOR.)
Current OS installation type is 'Client'.
RAS supported: True
FtpControlStream#21454193 - Created connection from 127.0.0.1:60360 to 93.184.216.34:2121.
Associating FtpWebRequest#45004109 with FtpControlStream#21454193
FtpControlStream#21454193 - Received response [220 ...]
FtpControlStream#21454193 - Sending command [USER username]
FtpControlStream#21454193 - Received response [331 Password required for username]
FtpControlStream#21454193 - Sending command [PASS ********]
FtpControlStream#21454193 - Received response [230 Logged on]
FtpControlStream#21454193 - Sending command [OPTS utf8 on]
FtpControlStream#21454193 - Received response [202 UTF8 mode is always enabled. No need to send this command.]
FtpControlStream#21454193 - Sending command [PWD]
FtpControlStream#21454193 - Received response [257 "/" is current directory.]
FtpControlStream#21454193 - Sending command [TYPE I]
FtpControlStream#21454193 - Received response [200 Type set to I]
FtpControlStream#21454193 - Sending command [PASV]
FtpControlStream#21454193 - Received response [227 Entering Passive Mode (93,184,216,34,247,106)]
FtpControlStream#21454193 - Sending command [STOR file1.zip]
FtpControlStream#21454193 - Received response [150 Opening data channel for file upload to server of "/file1.zip"]
FtpControlStream#21454193 - Received response [226 Successfully transferred "/file1.zip"]
FtpWebRequest#45004109::(Releasing FTP connection#21454193.)
FtpWebRequest#58870012::.ctor(ftp://ftp.example.com/file2.zip)
FtpWebRequest#58870012::GetRequestStream(Method=STOR.)
Associating FtpWebRequest#58870012 with FtpControlStream#21454193
FtpControlStream#21454193 - Sending command [PASV]
FtpControlStream#21454193 - Received response [227 Entering Passive Mode (93,184,216,34,247,142)]
FtpControlStream#21454193 - Sending command [STOR file2.zip]
FtpControlStream#21454193 - Received response [150 Opening data channel for file upload to server of "/file2.zip"]
FtpControlStream#21454193 - Received response [226 Successfully transferred "/file2.zip"]
FtpWebRequest#58870012::(Releasing FTP connection#21454193.)

答案 1 :(得分:-2)

edtFTPnet看起来很有希望,FluentFTP

也是如此

然而,最后,对于这种类型的项目使用DLL程序集或库,无论是使用LGPL还是MIT或其他任何东西,都会有人用一个注入了DLL的DLL替换DLL进行恶意攻击。某种形式的恶意软件。因为源是免费提供的。

最后,最好编写自己的代码,并将代码直接嵌入可执行文件中。额外的努力是值得的安全。

所以我将此标记为已回答。评论表示赞赏。