<< Back to tutorials

Quick Storage API in C++ with the SFTP/FTP

Published {$created} by Carsten Blum


When building applications in C++, direct control over networking and file I/O is often required. Traditionally, setting up an FTP server for storage meant provisioning hardware, configuring firewalls, and handling SSL certificates manually. But today, with cloud FTP storage, you can skip all of that complexity.


Using a managed service like ftpGrid cloud FTP storage, developers can quickly integrate secure file uploads into their applications. Instead of maintaining your own FTP server, you can treat the cloud as a storage API — available over familiar protocols like FTP, FTPS, and SFTP.


This makes C++ programs perfect candidates for IoT devices, embedded systems, or performance-critical applications that need to push data into the cloud without relying on heavy SDKs or proprietary APIs.


In this tutorial, we’ll create a simple text file in C++ and upload it to ftpGrid using libssh2 and the SFTP protocol.


It is recommended to read our getting started with FTP/SFTP guide to create your account. To read more in-depth about ftpGrid managed FTP/SFTP cloud hosting checkout our guide to ftpGrid's cloud hosting.



Prepare your environment

You need libssh2 to run this example, on MacOs or Linux the commands would look like this:


#On MacOS:
brew install libssh2

#On Debian, or variants like Ubuntu:
sudo apt install libssh2-1-dev


To keep the C++ example a little short, we're not gonna create the upload file, like we have in the other tutorials like the Java tutorial or the Go tutorial.


echo 'Hello from C++ and ftpGrid!' > cpp-hello.txt



Step 2: Example C++ Program

Save this as sftp_example.cpp:

#include <libssh2.h>
#include <libssh2_sftp.h>
#include <iostream>
#include <fstream>
#include <cstring>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <unistd.h>

int main() {
    const char *hostname = "edge1.ftpgrid.com";
    const char *username = "PREFIX.username";
    const char *password = "password";
    const char *local_path = "cpp-hello.txt";
    const char *remote_path = "cpp-hello.txt";
    int port = 22;

    // Initialize libssh2
    if (libssh2_init(0) != 0) {
        std::cerr << "libssh2 initialization failed" << std::endl;
        return 1;
    }

    // Create socket and connect
    hostent *host = gethostbyname(hostname);
    if (!host) {
        std::cerr << "Failed to resolve hostname" << std::endl;
        return 1;
    }

    int sock = socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(port);
    sin.sin_addr.s_addr = *(unsigned long*)host->h_addr;

    if (connect(sock, (struct sockaddr*)(&sin), sizeof(sockaddr_in)) != 0) {
        std::cerr << "Failed to connect to " << hostname << std::endl;
        return 1;
    }

    // Start SSH session
    LIBSSH2_SESSION *session = libssh2_session_init();
    if (libssh2_session_handshake(session, sock)) {
        std::cerr << "SSH session handshake failed" << std::endl;
        return 1;
    }

    // Authenticate
    if (libssh2_userauth_password(session, username, password)) {
        std::cerr << "Authentication failed" << std::endl;
        return 1;
    }

    // Create SFTP session
    LIBSSH2_SFTP *sftp = libssh2_sftp_init(session);
    if (!sftp) {
        std::cerr << "Unable to init SFTP session" << std::endl;
        return 1;
    }

    // Open remote file
    LIBSSH2_SFTP_HANDLE *sftp_handle =
        libssh2_sftp_open(sftp, remote_path,
                          LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
                          S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);

    if (!sftp_handle) {
        std::cerr << "Unable to open remote file" << std::endl;
        return 1;
    }

    // Read local file and upload
    std::ifstream local(local_path, std::ios::binary);
    if (!local) {
        std::cerr << "Unable to open local file" << std::endl;
        return 1;
    }

    char buffer[1024];
    while (local) {
        local.read(buffer, sizeof(buffer));
        std::streamsize nread = local.gcount();
        if (nread > 0) {
            char *ptr = buffer;
            while (nread > 0) {
                int rc = libssh2_sftp_write(sftp_handle, ptr, nread);
                if (rc < 0) break;
                ptr += rc;
                nread -= rc;
            }
        }
    }
    local.close();

    libssh2_sftp_close(sftp_handle);
    libssh2_sftp_shutdown(sftp);
    libssh2_session_disconnect(session, "Normal Shutdown");
    libssh2_session_free(session);
    close(sock);
    libssh2_exit();

    std::cout << "Uploaded " << local_path << " to " << remote_path << std::endl;
    return 0;
}


Step 3: Compile the program

On macOS or Linux:

g++ sftp_example.cpp -o sftp_example \
  -I$(brew --prefix libssh2)/include \
  -L$(brew --prefix libssh2)/lib \
  -lssh2


Step 4: Run the program

./sftp_example


Expected output:

Uploaded cpp-hello.txt to cpp-hello.txt


Conclusion

With just a few lines of C++ code, you connected to ftpGrid via SFTP and uploaded a file into cloud FTP storage. This approach turns ftpGrid into a simple Storage API that works across programming languages — including low-level C++ projects.


Start your journey with our FTP Cloud Storage pillar page or follow the Quick Start guide to set up your own cloud FTP account in minutes.



Signup now
© 2025 ftpGrid

ftpGrid ApS
Branebjerg 24
DK-5471
Gamby
Denmark

Looking for an all-in-one time tracking, timesheet, and invoicing solution - visit our Devanux sister company Nureti at https://nureti.com.

Preview Devanux’s upcoming project Pictoguide – a visual support tool designed to bring structure and clarity to people with ASD.