c++ curl下载和上传数据——c++(学习一)

首先必须感谢稀泥蟹大神的这篇文章。还有官网让我学习和使用了curl这个库。具体的curl的详解,请前往那里观看。我这里就是用c++封装了一下。还有说明一下,我这个是用在我的cocos2dx游戏里的。所以如果单独拿出来有问题的话还望指出,OK,直接上干货吧!随便提一下,使用它的时候应该开个线程。不然会一直阻塞在那里!!

//.hpp
#ifndef FCFTestNetWorkManager_hpp
#define FCFTestNetWorkManager_hpp

#include <stdio.h>
#include "curl.h"
#include <string.h>

using namespace std;

typedef std::function<void (string & response)>SuccessFinishedCallBack;//请求成功,有数据返回

class FCFTestNetWorkManager{
public:
    //使用单例
    static FCFTestNetWorkManager* getInstance();
    //使用get方法
    int  GetHttpRequest(const string & strUrl,SuccessFinishedCallBack callback);
    //使用post方法
    int  PostHttpRequest(const string & strUrl,const string & filePath,map<string,string>params,SuccessFinishedCallBack callback);
public:
    //设置回调
    void setSuccesseCallBack(SuccessFinishedCallBack callBack);
    //设置m_debug
    void setDebug(bool debug);
    //返回的数据处理
    static size_t write_data(void * buffer,size_t size, size_t nmenb,void * lpvoid);
    //debug
    static int onDebug(CURL * curl,curl_infotype itype,char * pData,size_t size,void * lpvoid);
    //进度
    static int updateProgress(void* ptr,double rDlTotal,double rDlNow,double rUlTotal,double rUlNow);
private:
    static FCFTestNetWorkManager * __instance;
    FCFTestNetWorkManager();
    ~FCFTestNetWorkManager();
    bool m_debug;
    SuccessFinishedCallBack SuccessCallBack;
};


#endif /* FCFTestNetWorkManager_hpp */
.cpp
#include "FCFTestNetWorkManager.hpp"

FCFTestNetWorkManager* FCFTestNetWorkManager::__instance = NULL;
FCFTestNetWorkManager* FCFTestNetWorkManager::getInstance()
{
    if (NULL == __instance) {
        __instance = new FCFTestNetWorkManager();
    }
    return __instance;
}

FCFTestNetWorkManager::FCFTestNetWorkManager():m_debug(false),SuccessCallBack(nullptr)
{

}

FCFTestNetWorkManager::~FCFTestNetWorkManager()
{

}

void FCFTestNetWorkManager::setSuccesseCallBack(SuccessFinishedCallBack callBack)
{
    SuccessCallBack = callBack;
}

void FCFTestNetWorkManager::setDebug(bool debug)
{
    m_debug = debug;
}

int FCFTestNetWorkManager::onDebug(CURL * curl,curl_infotype itype,char * pData,size_t size,void * lpvoid)
{
    if (itype == CURLINFO_TEXT) {
        printf("[text] %s\n",pData);
    }else if(itype == CURLINFO_HEADER_IN){
        printf("[HEADER_IN] %s\n",pData);
    }else if(itype == CURLINFO_HEADER_OUT){
        printf("[HEADER_IN] %s\n",pData);
    }else if(itype == CURLINFO_DATA_IN){
        printf("[HEADER_IN] %s\n",pData);
    }else if(itype == CURLINFO_DATA_OUT){
        printf("[HEADER_IN] %s\n",pData);
    }
    return (int)itype;
}

size_t FCFTestNetWorkManager::write_data(void * buffer,size_t size, size_t nmenb,void * lpvoid)
{
    string * str = dynamic_cast<string *>((string*)lpvoid);
    if (NULL == str || NULL == buffer) {
        return -1;
    }
    char * pData = (char *)buffer;
    str->append(pData,size*nmenb);
    return nmenb;
}

int FCFTestNetWorkManager::updateProgress(void* ptr,double rDlTotal,double rDlNow,double rUlTotal,double rUlNow)
{
    CCLOG("进度%f",rUlNow);
    return 0;
}

//get请求
int FCFTestNetWorkManager::GetHttpRequest(const string & strUrl,SuccessFinishedCallBack callback)
{
    string strResponse;//返回数据
    CURL * curl;
    CURLcode res;

    curl_global_init(CURL_GLOBAL_DEFAULT);//

    curl = curl_easy_init();//初始化句柄

    if (NULL == curl) {
        return CURLE_FAILED_INIT;
    }
    if(m_debug){
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);//这个CURLOPT_VERBOSE设为1,将显示出所有发送的实体协议的细节
        curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, onDebug);//这里将调用onDebug调试所有信息
    }
    curl_easy_setopt(curl,CURLOPT_URL,strUrl.c_str());//设置url
    curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,write_data);//调用处理函数
    curl_easy_setopt(curl,CURLOPT_WRITEDATA, (void *)&strResponse);//返回的数据,这里可以加个函数指针
    curl_easy_setopt(curl,CURLOPT_CONNECTTIMEOUT, 3);//设置链接时长
    res = curl_easy_perform(curl);//开始下载
    if (res == CURLE_OK) {
        callback(strResponse);
    }
    curl_global_cleanup();
    curl_easy_cleanup(curl);//
    return res;
}

//post请求
int  FCFTestNetWorkManager::PostHttpRequest(const string & strUrl,const string & filePath,map<string,string>params,SuccessFinishedCallBack callback)
{
    string strResponse;//返回数据
    int progress;
    CURL * curl;
    CURLcode res;

    struct curl_httppost * post = NULL;
    struct curl_httppost * last = NULL;
    struct curl_slist * headers = NULL;
    static const char buf[] = "Expect:";
    //配置上传文件的表单
    if (!filePath.empty()) {
        curl_formadd(&post,&last,
                     CURLFORM_COPYNAME,"pic",
                     CURLFORM_FILE,filePath.c_str(),
                     CURLFORM_CONTENTTYPE,"image/jpeg",
                     CURLFORM_END);
    }
    //配置参数
    for (auto iter = params.begin(); iter != params.end(); iter++) {
        curl_formadd(&post, &last,
                     CURLFORM_COPYNAME,iter->first.c_str(),
                     CURLFORM_COPYCONTENTS,iter->second.c_str(),
                     CURLFORM_END);
    }
    //
    curl = curl_easy_init();//初始化句柄

    if (NULL == curl) {
        return CURLE_FAILED_INIT;
    }
    if(m_debug){
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);//这个CURLOPT_VERBOSE设为1,将显示出所有发送的实体协议的细节
        curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, onDebug);//这里将调用onDebug调试所有信息
    }
    headers = curl_slist_append(headers, buf);//
    curl_easy_setopt(curl, CURLOPT_POST, 1);
    curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    curl_easy_setopt(curl, CURLOPT_HTTPPOST,post);//表单
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&strResponse);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,write_data);
    curl_easy_setopt(curl, CURLOPT_NOPROGRESS,false);//是否需要进度
    curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, updateProgress);//进度函数
    curl_easy_setopt(curl, CURLOPT_PROGRESSDATA,progress);//进度数据
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT,5);//连接时间
    res = curl_easy_perform(curl);
    if (res == CURLE_OK) {
        callback(strResponse);
    }
    curl_global_cleanup();
    curl_easy_cleanup(curl);
    curl_formfree(post);
    curl_slist_free_all(headers);
    return res;
}
//使用get
FCFTestNetWorkManager::getInstance()->GetHttpRequest(requestUrl, [](string & response){
        log("%s",response.c_str());
});
//使用post
FCFTestNetWorkManager::getInstance()->PostHttpRequest(requestUrl, getImgPath(), params, [](string & response){
        log("%s",response.c_str());
});
C++ 中使用 libcurl 下载文件通常涉及以下几个步骤。首先,你需要包含必要的库头文件,并初始化 libcurl。这里是一个简单的示例: ```cpp #include <curl/curl.h> #include <iostream> size_t write_callback(char* ptr, size_t size, size_t nmemb, void* userdata) { // 这里将数据写入到文件流 FILE* file = (FILE*)userdata; return fwrite(ptr, size, nmemb, file); } void download_file(const char* url, const char* filename) { CURL *curl; CURLcode res; // 初始化curl会话 curl_global_init(CURL_GLOBAL_DEFAULT); // 创建并初始化curl指针 curl = curl_easy_init(); if(curl) { // 设置下载URL curl_easy_setopt(curl, CURLOPT_URL, url); // 打开本地文件准备写入 FILE* outputFile = fopen(filename, "wb"); if(outputFile == nullptr) { std::cerr << "Failed to open output file." << std::endl; return; } curl_easy_setopt(curl, CURLOPT_WRITEDATA, outputFile); // 设置回调函数处理下载数据 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); // 开始下载 res = curl_easy_perform(curl); if(res != CURLE_OK) { std::cerr << "Error downloading file: " << curl_easy_strerror(res) << std::endl; } // 关闭文件和清理资源 fclose(outputFile); curl_easy_cleanup(curl); } // 清理libcurl全局环境 curl_global_cleanup(); } int main() { std::string url = "http://example.com/file.zip"; std::string save_path = "file.zip"; // 想要保存的文件名 try { download_file(url.c_str(), save_path.c_str()); std::cout << "Download completed successfully." << std::endl; } catch(...) { std::cerr << "An error occurred during the download." << std::endl; } return 0; } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值