首页 > C++使用curl提交分块大文件,curl参数选取问题

C++使用curl提交分块大文件,curl参数选取问题

能否详细讲解一下对应参数的含义?
还有对应curl_form表单的构造?
再就是代码上有什么风格问题?下面是我实现的单个小文件整个上传的代码,因为要改动成大文件分块还没改完,所以可能看上去代码有点乱。
使用回调函数READFUNCTION上传的时候,指定好回调函数,但是回调函数的第二和第三参数是没有被指定的,换而言之就是每次读取的数据量不定,curl如何靠这一个回调上传完所有数据呢?

    struct curl_httppost *formpost = NULL;
    struct curl_httppost *lastptr = NULL;
    QString filename_str("C:\xxxx.xxx");
    FILE *fp;
    fp = fopen("C:\xxxx.xxx","rb");
    char dispos[256] = "Content-Disposition:attachment;";
    strcat(dispos, filename_str.toStdString().c_str());
    std::stringstream rangeStream;
    rangeStream << "Content-Range:bytes " << ftell(fp) - UPLOADBLOCKSIZE << "-" << ftell(fp)-1 << "/" << UPLOADBLOCKSIZE;
    std::string contentRange = rangeStream.str();
    list = curl_slist_append(list, contentRange.c_str());
    list = curl_slist_append(list, "Content-Type:multipart/form-data");
    list = curl_slist_append(list, "Accept:application/json,text/javascript,*/*;q=0.01");
    list = curl_slist_append(list, dispos);
    list = curl_slist_append(list, "Accept-Language: zh-cn");
    list = curl_slist_append(list, "Connection: Keep-Alive");
    list = curl_slist_append(list, "Expect:");
    curl_formadd(&formpost,
        &lastptr,
        CURLFORM_COPYNAME, "title",
        CURLFORM_COPYCONTENTS, "",
        CURLFORM_END);
    //XXXXXXXXX  add一堆其他的表单数据
    curl_formadd(&formpost,
        &lastptr,
        CURLFORM_COPYNAME, "files[]",
        CURLFORM_FILE, filename.c_str(),
        CURLFORM_FILENAME, m_str.toStdString().c_str(),
        CURLFORM_END);
    //上面就是现在的上传主参数,已经实现了单个小文件的上传,对于大文件分块还是迷茫状态
    //curl_formadd(&formpost,
    //    &lastptr,
    //    CURLFORM_PTRNAME, "file",
    //    CURLFORM_PTRCONTENTS,fp,
    //    CURLFORM_CONTENTSLENGTH, UPLOADBLOCKSIZE,
    //    CURLFORM_END); 
    //UPLOADBLOCKSIZE为定义的一个宏,指定分块大小的,注掉的这句话的用意是找到文件的指针fp,读一个偏移,第二次读的时候,fread更新一下fp,fp为指定的文件名指针
    curl_formadd(&formpost,
        &lastptr,
        CURLFORM_CONTENTTYPE, "multipart/form-data",
        CURLFORM_END);
    curl_formadd(&formpost,&lastptr,CURLFORM_CONTENTHEADER,list,CURLFORM_END);
    curl = curl_easy_init();
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, 20L);
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
        curl_easy_setopt(curl, CURLOPT_URL, uploadurl.c_str());
        curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, static_cast<int(*)(void*, int, int, void*)>(
            [](void* data, int size, int cnt, void* userData)->int
        {
            std::vector<char>* buf = static_cast<std::vector<char>*>(userData);
            buf->insert(buf->end(), static_cast<char*>(data), static_cast<char*>(data)+(size * cnt));
            return cnt;
        }
        ));
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buf);
        int code = curl_easy_perform(curl);

        curl_formadd(&formpost,
        &lastptr,
        CURLFORM_COPYNAME, "files[]",
        CURLFORM_BUFFER, filename.c_str(),//filename
        CURLFORM_BUFFERPTR, postdata,//the uploaded data
        CURLFORM_BUFFERLENGTH, strlen(postdata),//the length of uploaded data
        CURLFORM_CONTENTTYPE, "multipart/form-data",//contenttype
        CURLFORM_END);

这就是分段的表单替换掉就好了,需要自己进行指针postdata的偏移控制。

READFUNCITON所指定的回调函数最好和CURLFORM_STREAM进行配合。

使用回调函数READFUNCTION上传的时候,指定好回调函数,但是回调函数的第二和第三参数是没有被指定的,换而言之就是每次读取的数据量不定,curl如何靠这一个回调上传完所有数据呢?
这个在指定了回调函数的情形下,curl会尽可能的去传递数据,当指定的回调函数返回0的时候,表示上传完成。

学习资料详情参见:
https://curl.haxx.se/libcurl/c/curl_easy_setopt.html
https://curl.haxx.se/libcurl/c/curl_formadd.html
http://blog.csdn.net/hzyong_c/article/details/7773494
http://www.darkbull.net/opensource/bad/libcurl_tutorial/#
http://www.seanyxie.com/libcurl%E4%B8%8B%E8%BD%BD%E5%AE%89%E8%A3%85%E5%92%8C%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95/

自问自答了。

【热门文章】
【热门文章】