C# - Download file using ftp over ssh from one rem

2019-09-06 14:29发布

问题:

I have requirement to download large files (20GB+) from one remote server to another remote server in C#. We already make ssh connections for other file operations. We need to initiate ftp download from ssh session in binary mode (this is remote server requirement to deliver file in specific format). Question - How do I send ftp command in ssh session to make connection with credentials and set mode as 'bin'? Basically equivalent of following using ssh:

FtpWebRequest request =(FtpWebRequest)WebRequest.Create(
        @"ftp://xxx.xxx.xxx.xxx/someDirectory/someFile");

request.Credentials = new NetworkCredential("username", "password");
request.UseBinary = true;
request.Method = WebRequestMethods.Ftp.DownloadFile;

FtpWebResponse response = (FtpWebResponse)request.GetResponse();

回答1:

SSH is a "Secure SHell" This is like a cmd prompt in that you give it commands to run. It is not FTP. SSH could execute an FTP utility or application.

SSH does have something called SFTP (or SSH File Transfer Protcol) but there is nothing built into .NET (i.e. the BCL) to do that. FtpWebRequest does not support SFTP.

Despite sharing "FTP" they're different protocols and are not compatible with each other.

If you want to initiate an FTP download, you'll have to tell SSH to execute a utility of some sort. If you want to initiate an SFTP transfer you can issue the sftp command. But, the other end will need to support sftp. Alternatively you an issue the scp command (secure copy); but again, the other end will need to support that protocol (it's different from SFTP and FTP)...

If you want to write the other end, you'll have to find a third-party library that does SFTP or SCP...



回答2:

My favorite lib to achieve what you need is Chilkat from ChilkatSoft (Disclaimer: I am just a paying user with no affiliation to the company).

Chilkat.SFtp sftp = new Chilkat.SFtp();

//  Any string automatically begins a fully-functional 30-day trial.
bool success;
success = sftp.UnlockComponent("Anything for 30-day trial");
if (success != true) {
    MessageBox.Show(sftp.LastErrorText);
    return;
}

//  Set some timeouts, in milliseconds:
sftp.ConnectTimeoutMs = 5000;
sftp.IdleTimeoutMs = 10000;

//  Connect to the SSH server.
//  The standard SSH port = 22
//  The hostname may be a hostname or IP address.
int port;
string hostname;
hostname = "www.my-ssh-server.com";
port = 22;
success = sftp.Connect(hostname,port);
if (success != true) {
    MessageBox.Show(sftp.LastErrorText);
    return;
}

//  Authenticate with the SSH server.  Chilkat SFTP supports
//  both password-based authenication as well as public-key
//  authentication.  This example uses password authenication.
success = sftp.AuthenticatePw("myLogin","myPassword");
if (success != true) {
    MessageBox.Show(sftp.LastErrorText);
    return;
}

//  After authenticating, the SFTP subsystem must be initialized:
success = sftp.InitializeSftp();
if (success != true) {
    MessageBox.Show(sftp.LastErrorText);
    return;
}

//  Open a file on the server:
string handle;
handle = sftp.OpenFile("hamlet.xml","readOnly","openExisting");
if (handle == null ) {
    MessageBox.Show(sftp.LastErrorText);
    return;
}

//  Download the file:
success = sftp.DownloadFile(handle,"c:/temp/hamlet.xml");
if (success != true) {
    MessageBox.Show(sftp.LastErrorText);
    return;
}

//  Close the file.
success = sftp.CloseHandle(handle);
if (success != true) {
    MessageBox.Show(sftp.LastErrorText);
    return;
}


标签: c# ssh ftp