ftpclient-cpp
ftpclient-cpp copied to clipboard
Upload file to FTP server (Ubuntu)
Hi! @embeddedmz
Im working with c++ code in Ubuntu and want to upload files/images to my FTP server. See attached images. How could I solve this? I have installed libcurl.
Thanks in advance!
Hello,
First of all, you must put your code inside a function (ex: int main() { // put code here }).
I ll try to give you an example before the end of the day that you can build on Ubuntu without CMake.
If you don't connect a secure FTP server (SFTP, FTPS/FTPES), you don't need to use the methode SetInsecure(true). Also, if the FTP server is not an active one (very rare), you must not set active to true.
Regards.
Thank you very much!! I will put the code inside an upload() function which will have an input argument as a string. The input variable is a JPG image. @embeddedmz
@victoriastraberg I tested this example with an FTP server hosted at 192.168.1.17:21 on my local network and a user account named "test" with a password "0123456789C++" :
#include "FTPClient.h"
#include <iostream>
using namespace embeddedmz;
int main()
{
// CFTPClient is allocated on the main function's stack
CFTPClient ftpClient([](const std::string& strLogMsg)
{ std::cout << strLogMsg << std::endl; });
// Initialize a session
ftpClient.InitSession("192.168.1.17", 21, "test", "0123456789C++");
// Create dummy test file
std::ofstream testFileStream("test_upload.txt");
testFileStream << "This file is uploaded via FTPClient-C++ API.\n"
"If this file exists, that means that the test is passed.\n";
testFileStream.close();
// Upload "test_upload.txt" (relative path to the executable) to "/uploaded_file.txt" (distant file path on the FTP server)
if (ftpClient.UploadFile("test_upload.txt", "uploaded_file.txt"))
{
std::cout << "OK.\n";
}
else
{
std::cout << "Error.\n";
}
// Explicit session cleanup
ftpClient.CleanupSession();
// Remove dummy test file
remove("test_upload.txt");
}
You can copy/paste that code in a main.cpp file that you can place in the same directory as the ftpclient-cpp/FTP/ and run this command in a terminal to compile the program :
g++ -DLINUX main.cpp FTPClient.cpp CurlHandle.cpp -lcurl -o testUpload
Explanations :
-DLINUX : you define a preprocessor macro 'LINUX' so you can enable the parts of the code that are intended for a Linux platform (it's like adding #define LINUX before #include "FTPClient.h").
-lcurl : You link the executable to libcurl shared object (library).
-o testUpload : The generated program will be named testUpload
I didn't add an argument to tell the compiler where the header files (.h) are (the argument is -I. the dot represents the current directory) since they are in the same directory as the source code cpp files.
To run the program : ./testUpload
It works! Thank you! @embeddedmz
See attached image below. I get these warnings when I write -DLINUX and when I remove -DLINUX I get "could not find #include <direct.h>..." How come?

LINUX preprocessor macro must be defined because in the header file there's these preprocessor instructions
#ifndef LINUX // If LINUX macro is NOT defined (e.g. we are compiling on MS Visual Studio) include <direct.h>
#include <direct.h> // mkdir() function in defined in <direct.h> on Windows platform
#endif
<direct.h> is a header that exists only with Microsoft Visual Studio C/C++ API and contains mkdir() function used to create a directory. LINUX macro must be defined so that the C++ GNU compiler's preprocessor doesn't include it in the code that will be compiled.
You can ignore the warnings, they are related to obsolete elements in newer versions of libcurl. You can't see them if the LINUX macro processor is not defined because the compiler stops when it comes across the error related to <direct.h>.
@embeddedmz Ok, thanks! :) Unfortunately I get every file stored in my local folder. How could I just upload the file without saving it locally?
You can specify the absolute path to the file e.g. "/home/user/test_upload.txt". In the example above, I used a relative path but you can also use absolute paths.
Example :
ftpClient.UploadFile("/home/user/test_upload.txt", "ftp_upload_dir/uploaded_file.txt")
On Windows :
ftpClient.UploadFile("C:\\test_upload.txt", "ftp_upload_dir/uploaded_file.txt")
@embeddedmz
Yes exactly. I already do like this - the problem is that the image still gets saved in the code folder. See here:
Can you show me the code using the upload() function ? (by the way, you don't need to use c_str() method when concatenating strings and when using UploadFile()).
I want to see how the image is stored in memory.
UploadFile has this "overloading" :
bool UploadFile(std::istream &inputStream, const std::string &strRemoteFile, const bool &bCreateDir = false,
curl_off_t fileSize = -1) const;
Depending on the code that retrieves an image from the camera and keeps it somewhere in memory, I could help you write the code that uses this overloading. Something like this :
unsigned char* mybuffer;
size_t length;
// allocate, fill, set length, as before
std::string data(mybuffer, length);
std::istringstream mb(data);
// Upload stream
ftpClient.UploadFile(mb, "image.jpg");
I can also add an overloading to the API having this signature if you want :
bool CFTPClient::UploadFile(const unsigned char* dataPtr, const size_t dataLength, const std::string &strRemoteFile, const bool &bCreateDir)