C++ 访问FTP客服端实现
ftp_client.h
struct ftp_opt
{
string url; // "ftp://127.0.0.1/test/20200920.bin"
string user_key; //"name:password"
};
struct ftp_upload_data
{
ftp_upload_data(string d, int number){ data = d; remaining = number;}
string data;
int remaining;
int written;
};
class ftp_client
{
public:
ftp_client(){ curl_global_init(CURL_GLOBAL_DEFAULT); }
~ftp_client(){ curl_global_cleanup(); }
//下载单个文件
string ftp_download(const ftp_opt& opt);
//上传文件
bool ftp_upload(const ftp_opt& opt, string data);
private:
int get_file_size(FILE *file)
{
int size = 0;
fseek(file, 0L, SEEK_END);
size = ftell(file);
fseek(file, 0L, SEEK_SET);
return size;
}
};
ftp_client.cpp
static size_t receive_data(void* buffer, size_t size, size_t nmemb, void* stream)
{
LOG_FILE(LOGI_INFO, "download size_t:[%d]", nmemb);
if(buffer == nullptr)
{
LOG_FILE(LOGI_INFO, "buffer为空");
return 0;
}
std::string* result = reinterpret_cast<std::string*>(stream);
result->append(reinterpret_cast<char*>(buffer), nmemb);
return nmemb;
}
static size_t upload_data(void* buffer, size_t size, size_t nmemb, void* stream)
{
if(stream)
{
ftp_upload_data* up = (ftp_upload_data*) stream;
int length = size * nmemb;
if(up->remaining > length)
{
memcpy(buffer, up->data.c_str() + up->written, length);
up->remaining = up->remaining - length;
up->written += length;
LOG_FILE(LOGI_INFO, "upload size_t:[%d]", length);
return length;
}else if(up->remaining)
{
int remainning = up->remaining;
memcpy(buffer, up->data.c_str() + up->written, up->remaining);
up->remaining = 0;
LOG_FILE(LOGI_INFO, "upload size_t:[%d]", remainning);
return remainning; //上传剩余文件
}
}
return 0; //结束回调不会执行这次上传
}
// vector<string> ftp_client::get_folder_data(const ftp_opt& opt)
// {
// vector<string> data;
// auto_rwlock loc(&loc_);
// return data;
// }
bool ftp_client::ftp_upload(const ftp_opt& opt, string data)
{
ftp_upload_data ftp_data(data,data.length());
// auto_rwlock loc(&loc_);
CURL *curl = curl_easy_init();
if(curl)
{
curl_easy_setopt(curl, CURLOPT_URL, opt.url.c_str());
curl_easy_setopt(curl, CURLOPT_USERPWD, opt.user_key.c_str());
curl_easy_setopt(curl, CURLOPT_READFUNCTION, upload_data);
curl_easy_setopt(curl, CURLOPT_READDATA, reinterpret_cast<void*>(&ftp_data));
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
curl_easy_setopt(curl, CURLOPT_INFILESIZE, get_file_size(fp));
curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1);
if(CURLE_OK == curl_easy_perform(curl))
{
LOG(LOGI_INFO, "crul-文件上传执行成功,size [%d]",data.size());
return true;
}else
{
LOG(LOGI_ERROR, "crul-文件上传执行失败");
}
curl_easy_cleanup(curl);
}
return false;
}
string ftp_client::ftp_download(const ftp_opt& opt)
{
// auto_rwlock loc(&loc_);
CURL *curl = curl_easy_init();
if(curl)
{
string result;
curl_easy_setopt(curl, CURLOPT_URL, opt.url.c_str());
curl_easy_setopt(curl, CURLOPT_USERPWD, opt.user_key.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receive_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, reinterpret_cast<void*>(&result));
if(CURLE_OK == curl_easy_perform(curl))
{
LOG(LOGI_INFO, "crul-文件下载执行成功,size [%d]",result.length());
return result;
}else
{
LOG(LOGI_ERROR, "crul-文件下载执行失败");
}
curl_easy_cleanup(curl);
}
return nullptr;
}