FTP multiple files in C# without reestablishing connection

前端 未结 2 1229
误落风尘
误落风尘 2020-12-06 22:28

The FTP protocol is designed to support a control channel, and use that control channel to tell the server to open TCP connections and transfer files.

The server sen

相关标签:
2条回答
  • 2020-12-06 22:47

    FtpWebRequest works on top of a connection pool. So it actually implicitly reuses an underlying FTP connection, as long as the FtpWebRequest.KeepAlive is set to its default value of true.

    When the KeepAlive is set to true, the underlying FTP (control) connection is not closed, when a request finishes. When you create another instance of the FtpWebRequest with the same host, port and username, the connection from previous request(s) is reused.


    Take this simple example of two file upload requests to the same FTP server:

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

    If you enable .NET network logging, you will see that only one FTP control connection is opened to the server:

    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.)
    

    Note that this does not work in .NET Core:
    Download multiple files over FTP using one connection in .NET Core

    0 讨论(0)
  • 2020-12-06 23:03

    edtFTPnet looks promising, as did FluentFTP

    However, in the end, using a DLL assembly or library for this type of project, whether with the LGPL or MIT or anything else, opens up the possibility of a malicious attack by someone replacing the DLL with one which was injected with some form of Malware. Because the source is freely available.

    In the end, it is better to write your own, with the code embedded directly in the executable. The extra effort is worth the security.

    So I am marking this as answered. The comments were appreciated.

    0 讨论(0)
提交回复
热议问题