libcurl下载到内存(String方法)

libcurl的文档中有getinmemory.c这个例子,把下载的网页写入自己定义的一个memorystruct中,看了这个例子的做法,它需要自己照顾内存的开辟,特别是需要在curl_easy_perform的调用函数中释放已开辟的内存,很不利于函数的封装,而且应用于multihandle的时候,运行时会出莫名其妙的assert错误。因此改写了一下,将下载的内容放入stl的string中,这样根本不需要自己照顾内存的开辟和释放。源代码如下:

#include "curl.h"

using namespace std;
static char errorBuffer[CURL_ERROR_SIZE];
static int writer(char *, size_t, size_t, string *);
static bool init(CURL *&, char *,string *);

int main()
{
    CURL *conn = NULL;
    CURLcode code;
 string buffer;
 
    curl_global_init(CURL_GLOBAL_DEFAULT);
    char* url="http://cool.haxx.se/";
 if (!init(conn,url,&buffer ))
    {
        fprintf(stderr, "Connection initializion failed\n");
        exit(EXIT_FAILURE);
    }
    code = curl_easy_perform(conn);
   
    if (code != CURLE_OK)
    {
        fprintf(stderr, "Failed to get '%s' [%s]\n", url, errorBuffer);
        exit(EXIT_FAILURE);
    }
 curl_easy_cleanup(conn);
 printf("%s\n",buffer.c_str());
    return 0;
    
}

static bool init(CURL *&conn, char *url,string *p_buffer)
{
    CURLcode code;
    conn = curl_easy_init();
    if (conn == NULL)
    {
        fprintf(stderr, "Failed to create CURL connection\n");
        exit(EXIT_FAILURE);
    }
    code = curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, errorBuffer);
    if (code != CURLE_OK)
    {
        fprintf(stderr, "Failed to set error buffer [%d]\n", code);
        return false;
    }
    code = curl_easy_setopt(conn, CURLOPT_URL, url);
    if (code != CURLE_OK)
    {
        fprintf(stderr, "Failed to set URL [%s]\n", errorBuffer);
        return false;
    }
    code = curl_easy_setopt(conn, CURLOPT_FOLLOWLOCATION, 1);
    if (code != CURLE_OK)
    {
        fprintf(stderr, "Failed to set redirect option [%s]\n", errorBuffer);
        return false;
    }
    code = curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writer);
    if (code != CURLE_OK)
    {
        fprintf(stderr, "Failed to set writer [%s]\n", errorBuffer);
        return false;
    }
    code = curl_easy_setopt(conn, CURLOPT_WRITEDATA, p_buffer);
    if (code != CURLE_OK)
    {
        fprintf(stderr, "Failed to set write data [%s]\n", errorBuffer);
        return false;
    }
    return true;
}

static int writer(char *data, size_t size, size_t nmemb, string *writerData)
{
    unsigned long sizes = size * nmemb;
    if (writerData == NULL) return 0;
    writerData->append(data, sizes);
    return sizes;
}


在C++中使用libcurl库连接FTP服务器并分段下载文件,libcurl是一个强大的HTTP和FTP客户端库,可以方便地处理网络请求。以下是一个简单的步骤描述: 1. 首先,确保已安装libcurl库,通常通过包管理器或源码编译安装。对于C++项目,你可以通过`#include <curl/curl.h>`引入头文件。 2. 创建一个CURL句柄(handle),初始化libcurl: ```cpp CURL *curl; CURLcode res; curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); if(curl) { // 设置FTP URL curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/path/to/file"); } ``` 3. 设置分块下载选项,例如设置缓冲区大小和断点续传(如果支持): ```cpp size_t buffer_size = 1024; // 可根据需要调整 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data_to_buffer); // 自定义回调函数 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &your_buffer); // 保存数据到内存区域 curl_easy_setopt(curl, CURLOPT_RANGE, "bytes=0-" + std::to_string(buffer_size - 1)); // 开始下载指定范围 ``` 这里`write_data_to_buffer`是你自定义的函数,负责将接收到的数据块存储到指定位置。 4. 执行FTP下载请求,并处理错误: ```cpp res = curl_easy_perform(curl); if(res != CURLE_OK) handle_error(curl_easy_strerror(res)); // 检查是否需要继续下载 if (/* FTP服务器支持断点续传 */ && /* 已下载部分小于总长度 */) { long total_size; curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &total_size); long current_offset = your_buffer.size(); // 获取当前已经下载的字节数 // 更新起始范围并继续下载 curl_easy_setopt(curl, CURLOPT_RANGE, "bytes=" + std::to_string(current_offset) + "-" + std::to_string(total_size - 1)); // 重复上述步骤 } // 关闭句柄并清理资源 curl_easy_cleanup(curl); curl_global_cleanup(); ``` 5. 定义`write_data_to_buffer`函数用于接收数据块并将它们写入文件或缓冲区,这个函数会根据实际需求编写。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值