Rebex


SFTP Tutorial

Applies to: Rebex Total Pack, Rebex File Transfer Pack, Rebex SSH Pack, Rebex SFTP

Table of content

#About Rebex SFTP

Rebex SFTP for .NET is a versatile file-transfer component for .NET languages (such as C# or VB.NET). It enables you to transfer files directly from your application using SFTP, a powerful and secure file-transfer protocol that runs over an SSH session. SSH and SFTP are nearly ubiquitous on Unix and Unix-like systems, with OpenSSH being the most common implementation. There is also a growing number of SSH/SFTP servers for Windows as well.

Please note that Rebex SFTP doesn't implement the FTPS protocol, also known as FTP over SSL or FTP over TLS - if this is what you need, please check out our Secure FTP component instead.

back to top...


#Namespaces and assemblies

To use the features of Rebex SFTP for .NET described here, you have to reference the Rebex.Sftp.dll, Rebex.Common.dll and Rebex.Networking.dll assemblies in your project. They contains the Sftp and other classes in Rebex.Net namespace.

In your source files, import the following namespace:

C#

using Rebex.Net;

C#

Imports Rebex.Net

back to top...


#SFTP basics - Connecting, logging in and disconnecting

Typical SFTP session goes like this:

  • Connect to the SSH server with SFTP support
  • Verify the server's fingerprint
  • Login - authenticate with user name and password
  • Browse directories and transfer files
  • Disconnect

And now let's look at some sample code.

C#

using Rebex.Net;
// ...

// create client and connect
Sftp client = new Sftp();

// to verify the server//s fingerprint:
//   a) check client.Fingerprint property after the
//      //Connect// method call
//    - or -
//   b) use client.FingerprintCheck event handler
//      to implement a fingerprint checker
client.Connect(hostname);
// verify the server//s fingerprint here unless using the event handler

// authenticate
client.Login(username, password);

// browse directories, transfer files, etc...
// ...

// disconnect
client.Disconnect();

VB.NET

Imports Rebex.Net
' ...

' create client and connect
Dim client As New Sftp

' to verify the server's fingerprint:
'   a) check client.Fingerprint property after the
'      'Connect' method call
'    - or -
'   b) use client.FingerprintCheck event handler
'      to implement a fingerprint checker
client.Connect(hostname)
' verify the server's fingerprint here unless using the event handler

' authenticate
client.Login(username, password)

' browse directories, transfer files, etc...
'...

' disconnect
client.Disconnect()

You might have noticed that the fingerprint verification is missing here. This is because implementing this is your responsibility. The fingerprint ensures the identity of the SFTP/SSH server and is the same every time you connect to it. In fact, it is a hash of the server's public key. The Sftp class makes it available as a Fingerprint property (string), which makes it easy to display or check it. If you don't check the fingerprint each time before(!) logging in, you are making yourself vulnerable to the man-in-the-middle attacks! In practice, the following approach is recommended:
1) When connecting to an unknown server (for the first time), let the user check and accept the fingerprint. Then save it along with the hostname of the server.
2) When connecting to a known server (whose hostname and fingerprint is already known), check whether the fingerprint presented by the server corresponds to the fingerprint saved before.

It is also possible to authenticate using your private key instead of password. Check out Public key authentication for more information.

back to top...


#Working with directories

Working with directories (folders) on the SFTP server is simple. The remote filesystem is organized in the same way as in Un*x. If you are used to Windows, watch out for the two differencies - a slash (/) is used instead of a backslash, and there is only a single root at "/", no drive letters. A typical path to a file might look like "/pub/incoming/test.zip", for example.

C#

// create client, connect and log in
Sftp client = new Sftp();
client.Connect("sftp.example.org");
client.Login("username", "password");

// determine current directory
Console.WriteLine("Current directory: {0}", client.GetCurrentDirectory());

// create the 'top' directory at the root level
client.CreateDirectory("/top");

// create the 'first' directory in the '/top' directory
client.CreateDirectory("/top/first");

// change the current directory to '/top'
client.ChangeDirectory("/top");

// create the 'second' directory in the current folder
// (note: we used a relative path this time)
client.CreateDirectory("second");

// remove the 'first' directory we created earlier
client.RemoveDirectory("first");

// change the current directory to a parent,
// (note: '..' has the same meaning as in Windows and Un*x
client.ChangeDirectory("..");

VB.NET

' create client, connect and log in
Dim client As New Sftp
client.Connect("sftp.example.org")
client.Login("username", "password")

' determine current directory
Console.WriteLine("Current directory: {0}", client.GetCurrentDirectory())

' create the 'top' directory at the root level
client.CreateDirectory("/top")

' create the 'first' directory in the '/top' directory
client.CreateDirectory("/top/first")

' change the current directory to '/top'
client.ChangeDirectory("/top")

' create the 'second' directory in the current folder
' (note: we used a relative path this time)
client.CreateDirectory("second")

' remove the 'first' directory we created earlier
client.RemoveDirectory("first")

' change the current directory to a parent,
' (note: '..' has the same meaning as in Windows and Un*x
client.ChangeDirectory("..")

back to top...


#Uploading and downloading files

File transfers are an essential part of the SFTP protocol and can be achieved using the GetFile and PutFile methods. They accept the path to the local file and the path to the remote file (both paths must include the filename) and return the number of bytes transferred (as long integer).

Other variants are also available that accept local and remote offsets, or streams instead of local files - it is easy to use .NET's MemoryStream to upload and download data from and to memory instead of disk.

C#

// create client, connect and log in
Sftp client = new Sftp();
client.Connect(hostname);
client.Login(username, password);

// upload the 'test.zip' file to the current directory at the server
client.PutFile(@"c:\data\test.zip", "test.zip");

// upload the 'index.html' file to the specified directory at the server
client.PutFile(@"c:\data\index.html", "/wwwroot/index.html");

// download the 'test.zip' file from the current directory at the server
client.GetFile("test.zip", @"c:\data\test.zip");

// download the 'index.html' file from the specified directory at the server
client.GetFile("/wwwroot/index.html", @"c:\data\index.html");

// upload a text using a MemoryStream
string message = "Hello from Rebex SFTP for .NET!";
byte[] data = System.Text.Encoding.Default.GetBytes(message);
System.IO.MemoryStream ms = new System.IO.MemoryStream(data);
client.PutFile(ms, "message.txt");

VB.NET

'create client, connect and log in
Dim client As New Sftp
client.Connect(hostname)
client.Login(username, password)

' upload the 'test.zip' file to the current directory at the server
client.PutFile("c:\data\test.zip", "test.zip")

' upload the 'index.html' file to the specified directory at the server
client.PutFile("c:\data\index.html", "/wwwroot/index.html")

' download the 'test.zip' file from the current directory at the server
client.GetFile("test.zip", "c:\data\test.zip")

' download the 'index.html' file from the specified directory at the server
client.GetFile("/wwwroot/index.html", "c:\data\index.html")

' upload a text using a MemoryStream
Dim message As String = "Hello from Rebex SFTP for .NET!"
Dim data As Byte() = System.Text.Encoding.Default.GetBytes(message)
Dim ms As New System.IO.MemoryStream(data)
client.PutFile(ms, "message.txt")

Unlike the FTP protocol, SFTP allows multiple concurrent operations at the same time. This makes it perfectly possible to transfer several files simultaneously over a single session and even browse directories at the same time. However, some buggy SFTP servers have problems with this, even though this is a standard SFTP feature.

back to top...


#List of files and directories

The following code snippet dispalys the list of files in the remote directory to a console:

C#

// create client, connect and log in
Sftp client = new Sftp();
client.Connect("sftp.example.org");
client.Login("username", "password");

// select the desired directory
client.ChangeDirectory("path");

// retrieve and display the list of files and directories
SftpItemCollection list = client.GetList();
foreach (SftpItem item in list)
{
    Console.Write(item.Modified.ToString("u"));
    Console.Write(item.Size.ToString().PadLeft(10, ' '));
    Console.Write(" {0}", item.Name);
    Console.WriteLine();
}

VB.NET

'create client, connect and log in
Dim client As New Sftp
client.Connect("sftp.example.org")
client.Login("username", "password")

' select the desired directory
client.ChangeDirectory("path")

' retrieve and display the list of files and directories
Dim list As SftpItemCollection = client.GetList()
Dim item As SftpItem
For Each item In list
    Console.Write(item.Modified.ToString("u"))
    Console.Write(item.Size.ToString().PadLeft(10, " "c))
    Console.Write(" {0}", item.Name)
    Console.WriteLine()
Next item

back to top...


#Transferring multiple files and directories

Upload or download of multiple files is a very common task. There are Download and Upload methods that can be used to transfer multiple files easily - just provide the source path (which can be a directory or contain wildcards), destination path and traversal mode.

C#

// create client, connect and log in
Sftp client = new Sftp();
client.Connect("sftp.example.org");
client.Login("username", "password");

// upload the content of 'c:\data' directory and all subdirectories
// to the '/wwwroot' directory at the server
client.Upload(@"c:\data\*", "/wwwroot", TraversalMode.Recursive);

// upload all '.html' files in 'c:\data' directory
// to the '/wwwroot' directory at the server
client.Upload(@"c:\data\*.html", "/wwwroot", TraversalMode.MatchFilesShallow,
     TransferMethod.Copy, ActionOnExistingFiles.OverwriteAll);

// download the content of '/wwwroot' directory and all subdirectories
// at the server to the 'c:\data' directory
client.Download("/wwwroot/*", @"c:\data", TraversalMode.Recursive);

// download all '.html' files in '/wwwroot' directory at the server
// to the 'c:\data' directory
client.Download("/wwwroot/*.html", @"c:\data", TraversalMode.MatchFilesShallow,
     TransferMethod.Copy, ActionOnExistingFiles.OverwriteAll);

VB.NET

' create client, connect and log in
Dim client As New Sftp
client.Connect("sftp.example.org")
client.Login("username", "password")

' upload the content of 'c:\data' directory and all subdirectories
' to the '/wwwroot' directory at the server
client.Upload("c:\data\*", "/wwwroot", TraversalMode.Recursive)

' upload all '.html' files in 'c:\data' directory
' to the '/wwwroot' directory at the server
client.Upload("c:\data\*.html", "/wwwroot", TraversalMode.MatchFilesShallow, _
  TransferMethod.Copy, ActionOnExistingFiles.OverwriteAll)

' download the content of '/wwwroot' directory and all subdirectories
' at the server to the 'c:\data' directory
client.Download("/wwwroot/*", "c:\data", TraversalMode.Recursive)

' download all '.html' files in '/wwwroot' directory at the server
' to the 'c:\data' directory
client.Download("/wwwroot/*.html", "c:\data", TraversalMode.MatchFilesShallow, _
  TransferMethod.Copy, ActionOnExistingFiles.OverwriteAll)

For transferring files from the current directory use asterisk (*). For example client.Download("*", localPath).

When transferring lots of files, things can occasionally go wrong due to unforeseen problems - to be informed about such errors, use ProblemDetected event that also makes it possible to select the desired next action. To stay informed about what is currently going on, use the TransferProgressChanged event.

C#

// add event handler that gets called when a problem is detected during the multi file
// transfer (this is optional) - the event handler can select the desired next action
client.ProblemDetected += new EventHandler<SftpProblemDetectedEventArgs>(client_ProblemDetected);

// add event handler that gets called when significant action occurs during
// traversing hierarchy structure (this is optional)
client.Traversing += new EventHandler<SftpTraversingEventArgs>(client_Traversing);

// add event handler that gets called when a significant action occurs during
// the batch transfer (this is optional)
client.TransferProgressChanged += new EventHandler<SftpTransferProgressChangedEventArgs>(client_TransferProgressChanged);

// upload or download files
client.Upload(localPath, remotePath, TraversalMode.Recursive);

// of course, the client_ProblemDetected, client_Traversing and client_TransferProgressChanged methods
// have to be implemented - check out the SftpBatchTransfer sample for more information

VB.NET

' add event handler that gets called when a problem is detected during the multi file
' transfer (this is optional) - the event handler can select the desired next action
AddHandler client.ProblemDetected, AddressOf client_ProblemDetected

' add event handler that gets called when significant action occurs during
' traversing hierarchy structure (this is optional)
AddHandler client.Traversing, AddressOf client_Traversing

' add event handler that gets called when a significant action occurs during
' the batch transfer (this is optional)
AddHandler client.TransferProgressChanged, AddressOf client_TransferProgressChanged

' upload or download files
client.Upload(localPath, remotePath, TraversalMode.Recursive)

' of course, the client_ProblemDetected, client_Traversing and client_TransferProgressChanged methods
' have to be implemented - check out the SftpBatchTransfer sample for more information

For more information about these events, check out the SFTP Batch Transfer sample application!

back to top...


#Getting information about SSH connection

You can easily get information about the SSH connection using properties of Sftp.Session that makes the underlying Rebex.Net.SshSession class available. Please note that you also need to reference Rebex.Networking.dll assembly from your project to be able to use the SshSession class.

C#

Sftp client = new Sftp();
client.Connect(hostname);

// The server's fingerprint
Console.WriteLine("Fingerprint: {0}", client.Session.Fingerprint);

// The Cipher property contains a lot of
// information about the current cipher
SshCipher cipher = client.Session.Cipher;
Console.WriteLine("Host key algorithm: {0}", cipher.HostKeyAlgorithm);
Console.WriteLine("Key exchange algorithm: {0}", cipher.KeyExchangeAlgorithm);
Console.WriteLine("Incoming MAC algorithm: {0}", cipher.IncomingMacAlgorithm);
Console.WriteLine("Incoming cipher: {0}", cipher.IncomingEncryptionAlgorithm);
Console.WriteLine("Outgoing MAC algorithm: {0}", cipher.OutgoingMacAlgorithm);
Console.WriteLine("Outgoing cipher: {0}", cipher.OutgoingEncryptionAlgorithm);
Console.WriteLine("Summary: {0}", cipher);

VB.NET

Dim client As New Sftp
client.Connect(hostname)

' The server's fingerprint
Console.WriteLine("Fingerprint: {0}", client.Session.Fingerprint)

' The Cipher property contains a lot of
' information about the current cipher
Dim cipher As SshCipher = client.Session.Cipher
Console.WriteLine("Host key algorithm: {0}", cipher.HostKeyAlgorithm)
Console.WriteLine("Key exchange algorithm: {0}", cipher.KeyExchangeAlgorithm)
Console.WriteLine("Incoming MAC algorithm: {0}", cipher.IncomingMacAlgorithm)
Console.WriteLine("Incoming cipher: {0}", cipher.IncomingEncryptionAlgorithm)
Console.WriteLine("Outgoing MAC algorithm: {0}", cipher.OutgoingMacAlgorithm)
Console.WriteLine("Outgoing cipher: {0}", cipher.OutgoingEncryptionAlgorithm)
Console.WriteLine("Summary: {0}", cipher)

back to top...


#Specifying SSH parameters

It is possible to affect many aspects of SSH such us specifying key exchange algorithm to use or which cipher suites to allow.

Depending on your scenario, it might be a good idea to disable weak cipher suites and only allowing the strong ones.

Please note that you also need to reference Rebex.Networking.dll assembly from your project to be able to use the SshParameters class.

C#

Sftp client = new Sftp();

// Create an instance of SshParameters class
// to specify desired arguments.
SshParameters par = new SshParameters();

// Disable transfer compression
par.Compression = false;

// Any key exchange method is acceptable.
par.KeyExchangeAlgorithms = SshKeyExchangeAlgorithm.Any;

// Only allow AES and 3DES encryption methods.
par.EncryptionAlgorithms = SshEncryptionAlgorithm.AES | SshEncryptionAlgorithm.TripleDES;

// Connect to the server.
// The third argument refers to the parameters class.
client.Connect(hostname, Sftp.DefaultPort, par);

VB.NET

Dim client As New Sftp

' Create an instance of SshParameters class
' to specify desired arguments.
Dim par As New SshParameters

' Disable transfer compression
par.Compression = False

' Any key exchange method is acceptable.
par.KeyExchangeAlgorithms = SshKeyExchangeAlgorithm.Any

' Only allow AES and 3DES encryption methods.
par.EncryptionAlgorithms = SshEncryptionAlgorithm.AES Or SshEncryptionAlgorithm.TripleDES

' Connect to the server.
' The third argument refers to the parameters class.
client.Connect(hostname, Sftp.DefaultPort, par)

back to top...


#Public key authentication

Instead of using a password to authenticate, it is often desirable to use public key cryptography. The SSH server keeps a database of public keys for each account - exact details of this depends on the server. For example, OpenSSH keeps the public keys in ~/.ssh/authorized_keys file in each account's home directory. Each public key has a corresponding private key that is kept secret by the client, usually in a file encrypted using a password. To authenticate to the server using public key cryptography, you need this private key. To generate the public/private key pair, either use the KeyGenerator sample application or another utility such as OpenSSH's ssh-keygen. Or write your own key generator using Rebex SSH Shell classes.

To authenticate using your private key, you have to load it into an SshPrivateKey instance. SshPrivateKey supports all the common private key file formats: PKCS#8 v1 and v2 or the traditional SSLeay compatible format. Support for other formats may be added on request.

Please note that you also need to reference Rebex.Networking.dll assembly from your project to be able to use the SshPrivateKey class.

C#

// create client and connect
Sftp client = new Sftp();
client.Connect(hostname);

// verify the server's fingerprint (client.Fingerprint)

SshPrivateKey privateKey = new SshPrivateKey("key_rsa.pem", "password");

// authenticate
client.Login(username, privateKey);

// ...

VB.NET

' create client and connect
Dim client As New Sftp
client.Connect(hostname)

' verify the server's fingerprint (client.Fingerprint)

Dim privateKey As New SshPrivateKey("key_rsa.pem", "password")

' authenticate
client.Login(username, privateKey)

' ...

Fingerprint verification was already discussed in SFTP basics.

back to top...


#Private and public key generation

Rebex SFTP can generate the private and public keys to use within public key authentication. To generate a key, use SshPrivateKey class's Generate method. Once the RSA or DSA key is generated, save it using Save and SavePublicKey methods, or use GetPublicKey to get the raw data of the public key.

Key generation is only supported in Rebex SFTP for .NET Framework builds, not in .NET Compact Framework version. However, if you purchase a license of Rebex SFTP for .NET CF, you are entitled to use the .NET Framework version as well. This makes it possible to generate your keys on a PC and then use them on your mobile device.

To be able to authenticate using your newly generated key, the public key has to be added to SSH server's database for your account. For example, in OpenSSH, the public keys are kept in ~/.ssh/authorized_keys each account's home directory.

The following code snippet shows how to generate a private key, save it (also the associated public key) and constructs the string to be added to OpenSSH ~/.ssh/authorized_keys file.

Please note that you also need to reference Rebex.Networking.dll assembly from your project to be able to use the SshPrivateKey class.

C#

// select the key algorithm (RSA or DSA) and key size
SshHostKeyAlgorithm algorithm = SshHostKeyAlgorithm.RSA;
int keySize = 1024;

// generate private key
SshPrivateKey privateKey = SshPrivateKey.Generate(algorithm, keySize);

// save the private key
privateKey.Save("key_rsa.pem", "password", null);

// save the public key
privateKey.SavePublicKey("key_rsa.pub");

// the only purpose of the rest of this sample
// is to construct the OpenSSH-style public key string

// get the raw form of SSH public key
byte[] rawPublicKey = privateKey.GetPublicKey();

// select the appropriate algorithm id
string publicKeyAlgorithm;
switch (algorithm)
{
    case SshHostKeyAlgorithm.RSA:
        publicKeyAlgorithm = "ssh-rsa";
        break;
    case SshHostKeyAlgorithm.DSS:
        publicKeyAlgorithm = "ssh-dss";
        break;
    default:
        throw new ApplicationException("Unsupported algorithm.");
}

// the string to be added to OpenSSH's ~/.ssh/authorized_keys file
string sshPublicKey = string.Format("{0} {1} username@hostname",
    publicKeyAlgorithm,
    Convert.ToBase64String(rawPublicKey));

// and display it
Console.WriteLine("Add the following line to your ~/.ssh/authorized_keys file:");
Console.WriteLine(sshPublicKey);
Console.WriteLine("(Modify 'username@hostname' to match your username and hostname.)");

VB.NET

' select the key algorithm (RSA or DSA) and key size
Dim algorithm As SshHostKeyAlgorithm = SshHostKeyAlgorithm.RSA
Dim keySize As Integer = 1024

' generate private key
Dim privateKey As SshPrivateKey = SshPrivateKey.Generate(algorithm, keySize)

' save the private key
privateKey.Save("key_rsa.pem", "password", Nothing)

' save the public key
privateKey.SavePublicKey("key_rsa.pub")

' the only purpose of the rest of this sample
' is to construct the OpenSSH-style public key string

' get the raw form of SSH public key
Dim rawPublicKey As Byte() = privateKey.GetPublicKey()

' select the appropriate algorithm id
Dim publicKeyAlgorithm As String
Select Case algorithm
    Case SshHostKeyAlgorithm.RSA
        publicKeyAlgorithm = "ssh-rsa"
    Case SshHostKeyAlgorithm.DSS
        publicKeyAlgorithm = "ssh-dss"
    Case Else
        Throw New ApplicationException("Unsupported algorithm.")
End Select

' the string to be added to OpenSSH's ~/.ssh/authorized_keys file
Dim sshPublicKey As String = String.Format("{0} {1} username@hostname", _
 publicKeyAlgorithm, _
 Convert.ToBase64String(rawPublicKey))

' and display it
Console.WriteLine("Add the following line to your ~/.ssh/authorized_keys file:")
Console.WriteLine(sshPublicKey)
Console.WriteLine("(Modify 'username@hostname' to match your username and hostname.)")

back to top...


#Using events and logging communication

In case something goes wrong, it is very useful to have a log of commands sent to the server and responses received from it for diagnostics purposes. To make this possible, the Sftp class declares the following events:

Event name Description
CommandSent Occurs when a command (request) is sent to the server.
ResponseRead Occurs when response is received from the server.
StateChanged Occurs when the session state changes, such as from Disconnected to Ready, from Ready to Sending or from Sending to Reading.
TransferProgress Occurs when a block of data is send or received.

The CommandSent or ResponseRead events are particularly useful for the purpose of generating a communication log and the TransferProgress event can be used by a GUI application to display amount of transfered data or a progress bar.

C#

Sftp client = new Sftp();
client.CommandSent += new SftpCommandSentEventHandler(client_CommandSent);
client.ResponseRead += new SftpResponseReadEventHandler(client_ResponseRead);
client.Connect("sftp.example.org");

//...
private void client_CommandSent(object sender, SftpCommandSentEventArgs e)
{
    Console.WriteLine("Command: {0}", e.Command);
}

private void client_ResponseRead(object sender, SftpResponseReadEventArgs e)
{
    Console.WriteLine("Response: {0}", e.Response);
}

VB.NET

Dim client As New Sftp
AddHandler client.CommandSent, AddressOf client_CommandSent
AddHandler client.ResponseRead, AddressOf client_ResponseRead
client.Connect("sftp.example.org")

'...
Public Sub client_CommandSent(ByVal sender As Object, ByVal e As  _
   SftpCommandSentEventArgs)
    Console.WriteLine("Command: {0}", e.Command)
End Sub

Public Sub client_ResponseRead(ByVal sender As Object, ByVal e As  _
 SftpResponseReadEventArgs)
    Console.WriteLine("Response: {0}", e.Response)
End Sub

back to top...


#Resuming file transfer

When file upload or download fails for some reason, it might be possible to resume the transfer instead of jast starting all over again. With the help of .NET's stream classes and Rebex SFTP's PutFile and GetFile methods, resuming the transfer where it ended is easy.

Resuming download:

C#

// create client, connect and log in
Sftp client = new Sftp();
client.Connect("sftp.example.org");
client.Login("username", "password");

// get the length of the remote file.
// (we need to know where to resume the transfer)
long remoteOffset = client.GetFileLength(remotePath);

// open the local file for writing
Stream local = File.OpenWrite(localPath);

// resume the transfer if there is more data available
if (local.Length < remoteOffset)
{
    // seek to the end and read the position
    local.Seek(0, SeekOrigin.End);
    remoteOffset = local.Position;

    // transfer data
    client.GetFile(remotePath, local, remoteOffset, -1);
}

// close the local file
local.Close();

VB.NET

'create client, connect and log in
Dim client As New Sftp
client.Connect("sftp.example.org")
client.Login("username", "password")

' get the length of the remote file
' (we need to know where to resume the transfer)
Dim remoteOffset As Long
remoteOffset = client.GetFileLength(remotePath)

' open the local file for writing
Dim local As Stream = File.OpenWrite(localPath)

' resume the transfer if there is more data available
If local.Length < remoteOffset Then

    ' seek to the end and read the position
    local.Seek(0, SeekOrigin.End)
    remoteOffset = local.Position

    ' transfer data
    client.GetFile(remotePath, local, remoteOffset, -1)
End If

' close the local file
local.Close()

Resuming upload:

C#

// create client, connect and log in
Sftp client = new Sftp();
client.Connect("sftp.example.org");
client.Login("username", "password");

// get the length of the remote file
// (we need to know where to resume the transfer)
long remoteOffset = client.GetFileLength("remotePath");

// open the local file for reading
Stream local = File.OpenRead("localPath");

// resume the transfer if there is more data available
if (remoteOffset < local.Length)
{
    // seek to the offset correspoding to the remote length
    local.Seek(remoteOffset, SeekOrigin.Begin);

    // transfer data
    client.PutFile(local, "remotePath", remoteOffset, -1);
}

// close the local file
local.Close();

VB.NET

'create client, connect and log in
Dim client As New Sftp
client.Connect("sftp.example.org")
client.Login("username", "password")

' get the length of the remote file
' (we need to know where to resume the transfer)
Dim remoteOffset As Long = client.GetFileLength(remotePath)

' open the local file for reading
Dim local As Stream = File.OpenRead(localPath)

' resume the transfer if there is more data available
If remoteOffset < local.Length Then

    ' seek to the offset correspoding to the remote length
    local.Seek(remoteOffset, SeekOrigin.Begin)

    ' transfer data
    client.PutFile(local, remotePath, remoteOffset, -1)
End If

' close the local file
local.Close()

Check out the ResumableTransfer sample application for a working implementation of transfer resuming code!

back to top...


#SCP protocol

SCP is a legacy file transfer protocol or rather a program, a secure analog of the rcp that runs over an SSH channel. This protocol has a very limited feature set and only supports file transfer. It has been superseded by SFTP, which was designed to replace it and provide a full remote-filesystem-like API. In most cases, using SFTP is a better choice. But when using legacy servers that don't support SFTP yet, SCP can still be useful.

C#

// create client, connect and log in
Scp client = new Scp();
client.Connect(hostname);
client.Login(username, password);

// upload the 'test.zip' file to the current directory at the server
client.PutFile(@"c:\data\test.zip", "test.zip");

// upload the 'index.html' file to the specified directory at the server
client.PutFile(@"c:\data\index.html", "/wwwroot/index.html");

// download the 'test.zip' file from the current directory at the server
client.GetFile("test.zip", @"c:\data\test.zip");

// download the 'index.html' file from the specified directory at the server
client.GetFile("/wwwroot/index.html", @"c:\data\index.html");

// create a subdirectory 'testdir' in the user's home folder
client.CreateDirectory("testdir");

// upload a text using a MemoryStream
string message = "Hello from Rebex SFTP for .NET!";
byte[] data = System.Text.Encoding.Default.GetBytes(message);
System.IO.MemoryStream ms = new System.IO.MemoryStream(data);
client.PutFile(ms, "message.txt");

VB.NET

'create client, connect and log in
Dim client As New Scp
client.Connect(hostname)
client.Login(username, password)

' upload the 'test.zip' file to the current directory at the server
client.PutFile("c:\data\test.zip", "test.zip")

' upload the 'index.html' file to the specified directory at the server
client.PutFile("c:\data\index.html", "/wwwroot/index.html")

' download the 'test.zip' file from the current directory at the server
client.GetFile("test.zip", "c:\data\test.zip")

' download the 'index.html' file from the specified directory at the server
client.GetFile("/wwwroot/index.html", "c:\data\index.html")

' create a subdirectory 'testdir' in the user's home folder
client.CreateDirectory("testdir")

' upload a text using a MemoryStream
Dim message As String = "Hello from Rebex SFTP for .NET!"
Dim data As Byte() = System.Text.Encoding.Default.GetBytes(message)
Dim ms As New System.IO.MemoryStream(data)
client.PutFile(ms, "message.txt")

back to top...


Back to tutorial list...