如何使用Crow C++连接非本地的FTP服务器
解决方案
Crow是一款HTTP/Web框架,本身不提供FTP传输的内置功能,你需要结合专门的C++ FTP客户端库(比如libcurl)来实现上传逻辑。以下是具体实现步骤和代码示例:
1. 准备FTP客户端库
推荐使用libcurl,它支持FTP上传且跨平台,你需要先在项目中集成libcurl库(通过包管理器或源码编译)。
2. 调整原有代码逻辑
原代码存在逻辑问题:app.run()是阻塞调用,进入后会一直运行Web服务,外层的while(true)循环没有实际作用;且每次循环重复定义路由也不合理。以下是修正后的代码,集成FTP上传功能:
#include <crow.h> #include <curl/curl.h> #include <iostream> #include <string> // 定义FTP上传函数 bool uploadToFtp(const std::string& content, const std::string& ftpHost, const std::string& ftpUser, const std::string& ftpPass, int ftpPort, const std::string& remoteFilePath) { CURL* curl = curl_easy_init(); if (!curl) { std::cerr << "Failed to initialize curl" << std::endl; return false; } // 设置FTP地址(格式:ftp://[用户名:密码@]主机:端口/远程文件路径) std::string ftpUrl = "ftp://" + ftpUser + ":" + ftpPass + "@" + ftpHost + ":" + std::to_string(ftpPort) + "/" + remoteFilePath; // 设置curl选项 curl_easy_setopt(curl, CURLOPT_URL, ftpUrl.c_str()); curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); // 设置要上传的内容来源为内存 curl_easy_setopt(curl, CURLOPT_READFUNCTION, [](char* ptr, size_t size, size_t nmemb, std::string* content) { size_t totalSize = size * nmemb; if (content->size() < totalSize) { totalSize = content->size(); } memcpy(ptr, content->data(), totalSize); content->erase(0, totalSize); return totalSize; }); curl_easy_setopt(curl, CURLOPT_READDATA, &content); // 设置上传内容的总长度 curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)content.size()); // 执行上传 CURLcode res = curl_easy_perform(curl); bool success = (res == CURLE_OK); if (!success) { std::cerr << "FTP upload failed: " << curl_easy_strerror(res) << std::endl; } curl_easy_cleanup(curl); return success; } int main() { crow::SimpleApp app; std::cout << "1: OPTION 1" << std::endl; std::cout << "2: OPTION 2" << std::endl; std::cout << "3: OPTION 3" << std::endl; int option; std::cout << "Enter option 1-3: "; std::cin >> option; std::string result; // 先确定要上传的内容 switch(option) { case 1: result = "Option 1"; break; case 2: result = "Option 2"; break; case 3: result = "Option 3"; break; default: std::cerr << "Invalid option" << std::endl; return 1; } // FTP配置信息,替换为你的实际参数 std::string ftpHost = "your-ftp-host"; std::string ftpUser = "your-ftp-username"; std::string ftpPass = "your-ftp-password"; int ftpPort = 21; // 通常FTP端口是21,若为SFTP则是22 std::string remoteFilePath = "uploaded_result.txt"; // 远程服务器上的文件名 // 上传到FTP服务器 bool uploadSuccess = uploadToFtp(result, ftpHost, ftpUser, ftpPass, ftpPort, remoteFilePath); // 定义Crow路由,返回上传状态 CROW_ROUTE(app, "/")([uploadSuccess, result]() { if (uploadSuccess) { return "Result \"" + result + "\" uploaded to FTP server successfully!"; } else { return "Failed to upload result to FTP server."; } }); // 启动Web服务 app.port(18080).multithreaded().run(); return 0; }
3. 关键说明
- 路由定义调整:将路由定义移到逻辑处理之后,避免重复定义;
app.run()只调用一次,因为它是阻塞函数,会一直运行Web服务。 - FTP上传逻辑:通过libcurl实现内存内容直接上传到FTP服务器,无需先写入本地文件。
- 参数替换:记得把代码中的FTP主机、用户名、密码、端口和远程文件路径替换为你的实际信息。
4. 编译注意事项
编译时需要链接libcurl库,比如在GCC下:
g++ your_app.cpp -o your_app -lcrow -lcurl
内容的提问来源于stack exchange,提问作者Afra Farkhooy
相关产品推荐
相关产品推荐

