牛骨文教育服务平台(让学习变的简单)
博文笔记

curl使用小结

创建时间:2015-08-05 投稿人: 浏览次数:927

最近在学习curl,顺便记录一下:

常用函数简要说明

  • curl_easy_init()
    初始化一个licurl简单会话,这个API应该最先调用,它会返回一个handle,供其他API使用。
  • curl_easy_cleanup()
    清除CURL指针,如果前面调用了curl_easy_init(),后面就一定要调用curl_easy_cleanup(),相当于释放资源。
  • curl_easy_setopt()
    给curl的easy handle设置一个传输选项,这是一个很重要的函数,也是用的最多的一个,如果你要对curl进行什么操作,大多需要透过这个API去设定。
  • curl_easy_perform()
    执行传输任务
  • curl_easy_getinfo()
    从curl handle提取相应的信息

curl_easy_setopt常用设置说明

  • CURLOPT_URL
    设定要访问的URL
  • CURLOPT_VERBOSE
    打开一些传输过程的信息,常用于调试时,查看信息
  • CURLOPT_FOLLOWLOCATION
    打开重定向跟踪
  • CURLOPT_WRITEFUNCTION、CURLOPT_WRITEDATA
    CURLOPT_WRITEFUNCTION:设置一个回调函数,用于保存接收到的数据
    回调函数:size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata);
    ptr:指向接收到的数据
    userdata:CURLOPT_WRITEDATA设置的参数
    写入数据的大小为size*nmemb
    CURLOPT_WRITEDATA:用于设定上面回调函数的最后一个参数
  • CURLOPT_HEADERFUNCTION、CURLOPT_HEADERDATA
    上面两个选项主要用于保存header data,使用方法可以参考CURLOPT_WRITEFUNCTION和CURLOPT_WRITEDATA
  • CURLOPT_NOPROGRESS、CURLOPT_PROGRESSFUNCTION、CURLOPT_PROGRESSDATA
    这三个选项主要用来得到当前任务的传输进度,具体用法可以参考下面的例子

curl_easy_getinfo常用设置说明

  • CURLINFO_REDIRECT_URL
    获取重定向的URL
  • CURLINFO_CONTENT_TYPE
    获取传输的数据类型
  • CURLINFO_SIZE_DOWNLOAD
    下载文件的大小
  • CURLINFO_TOTAL_TIME
    下载文件所花的总时间
  • CURLINFO_SPEED_DOWNLOAD
    下载文件的平均速度

例程

  • http post
INT32 libcurl_http_post(const CHAR * url, const CHAR * postFields)
{
    CURL *curl;
    CURLcode res;

    curl = curl_easy_init();
    if(curl) 
    {
        curl_easy_setopt(curl, CURLOPT_URL, url);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postFields);

        res = curl_easy_perform(curl);
        if(CURLE_OK != res)
        {
            curl_easy_cleanup(curl);
            return LIBCURL_RET_FAIL;
        }

        curl_easy_cleanup(curl);
    }

  return LIBCURL_RET_OK;
}
  • 获取重定向URL
INT32 libcurl_get_redirect_url(const CHAR * url)
{
    char *redirectUrl;

    CURLcode res;
    res = curl_global_init(CURL_GLOBAL_ALL);

    CURL *curl = curl_easy_init();
    if(curl) 
    {
        char *version = curl_version();
        printf("CURL version is %s
", version);            

        curl_easy_setopt(curl, CURLOPT_URL, url);        
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

        res = curl_easy_perform(curl);
        if(CURLE_OK == res) 
        {
            curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
            curl_easy_getinfo(curl, CURLINFO_REDIRECT_URL, &redirectUrl);
            printf("Redirect URL is : %s
", redirectUrl);
        }

        curl_easy_cleanup(curl);
        curl_global_cleanup();
    }

    return LIBCURL_RET_OK;
}
  • 获取http头
static size_t libcurl_http_get_header_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
    FILE *fp = (FILE *)stream;

    return fwrite(ptr, size, nmemb, fp); 
}

INT32 libcurl_http_get_header(const CHAR * url, const CHAR * pageSavePath)
{       
    CURL *curl;
    CURLcode res;
    FILE *fp;

    res = curl_global_init(CURL_GLOBAL_ALL);
    if(CURLE_OK != res)
    {
        return LIBCURL_RET_FAIL;
    }

    curl = curl_easy_init();
    if(curl) 
    {           

        if(NULL == (fp = fopen(pageSavePath, "w+")))
        {
            printf("Open file error
");
            return LIBCURL_RET_FAIL;            
        }

        curl_easy_setopt(curl, CURLOPT_URL, url);
        //curl_easy_setopt(curl, CURLOPT_HEADER, 1); 
        curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, libcurl_http_get_header_callback);  
        curl_easy_setopt(curl, CURLOPT_HEADERDATA, fp);    

        res = curl_easy_perform(curl);  
        if(CURLE_OK != res)
        {
            curl_easy_cleanup(curl);
            return LIBCURL_RET_FAIL;
        }

        curl_easy_cleanup(curl);
    }
    return LIBCURL_RET_OK;
}
  • 保存一个网页
static size_t libcurl_http_get_page_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
    FILE *fp = (FILE *)stream;
    size_t return_size = fwrite(ptr, size, nmemb, fp);

    return return_size;
}

INT32 libcurl_http_get_page(const char * url, const char *pageSavePath)
{
    CURL *curl;
    CURLcode res;
    FILE *fp = NULL;

    if(NULL == (fp =fopen(pageSavePath, "wb")))
    {
        printf("open fail
");
        fclose(fp);
        return LIBCURL_RET_FAIL;
    } 

    res = curl_global_init(CURL_GLOBAL_ALL);
    if(CURLE_OK != res)
    {
        return LIBCURL_RET_FAIL;
    }

    curl = curl_easy_init();
    if(curl) 
    {
        curl_easy_setopt(curl, CURLOPT_URL, url);
        curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, libcurl_http_get_page_callback); 
        curl_easy_setopt( curl, CURLOPT_WRITEDATA, (void *)fp); 

        res = curl_easy_perform(curl);
        if(CURLE_OK == res) 
        {      
            char *contentType;          
            res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &contentType);      
            if((CURLE_OK == res) && contentType)        
                printf("We received Content-Type: %s
", contentType);    
        }

        curl_easy_cleanup(curl);
    }

    fclose(fp);

    return LIBCURL_RET_OK;
}
  • 下载一个文件并显示下载进度
static size_t libcurl_file_download_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
    FILE *fp = (FILE *)stream;

    return fwrite(ptr, size, nmemb, fp); 
}

static INT32 libcurl_file_download_progress_callback(void *p,
                    double t, /* dltotal */
                     double d, /* dlnow */
                     double ultotal,
                     double ulnow)
{
    int currentPercent = 0;
    if(t != 0)
    {
        currentPercent = (int)((double)100*(d/t));  
    }

    printf("download percent : %d
", currentPercent);

    return LIBCURL_RET_OK;
}

INT32 libcurl_file_download(const CHAR *url, const CHAR * fileSavePath) 
{
    CURL *curl;
    CURLcode res;
    FILE *fp;

    res = curl_global_init(CURL_GLOBAL_ALL);

    curl = curl_easy_init();
    if(curl) 
    {
        if(NULL == (fp = fopen(fileSavePath, "w+")))
        {
            printf("Open file error
");
            return LIBCURL_RET_FAIL;            
        }

        curl_easy_setopt(curl, CURLOPT_URL, url);

        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, libcurl_file_download_callback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);

        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
        curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, libcurl_file_download_progress_callback);
        curl_easy_setopt(curl, CURLOPT_PROGRESSDATA,curl);
        //curl_easy_setopt(curl, CURLOPT_RANGE,"0-300000");
        //curl_easy_setopt(curl, CURLOPT_RANGE,"300001-600000");
        //curl_easy_setopt(curl, CURLOPT_RANGE,"600001-900000");
        //curl_easy_setopt(curl, CURLOPT_RANGE,"0-500000");

        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);                        // display debug msg

        res = curl_easy_perform(curl);
        if(CURLE_OK == res) 
        {
            double val;            
            char *contentType;      

            res = curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &val);
            if((CURLE_OK == res) && (val>0))
            printf("Data downloaded: %0.0f bytes.
", val);

            res = curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &val);
            if((CURLE_OK == res) && (val>0))
            printf("Total download time: %0.3f sec.
", val);

            res = curl_easy_getinfo(curl, CURLINFO_SPEED_DOWNLOAD, &val);
            if((CURLE_OK == res) && (val>0))
            printf("Average download speed: %0.3f kbyte/sec.
", val / 1024); 

            res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &contentType);      
            if((CURLE_OK == res) && contentType)        
                printf("Content-Type: %s
", contentType);    

        }

        if(fp)
            fclose(fp);

        curl_easy_cleanup(curl);
    }

    return LIBCURL_RET_OK;
}
  • ftp 上传
INT32 libcurl_ftp_upload_file(const CHAR * ftpAddress, const CHAR * localFilePath, const CHAR * userPwd)
{
    CURL *curl;
    CURLcode res;

    struct stat file_info;
    curl_off_t fsize;

    if(stat(localFilePath, &file_info)) 
    {
        printf("Can not open %s
", localFilePath);
        return LIBCURL_RET_FAIL;
    }

    fsize = (curl_off_t)file_info.st_size;

    FILE *fp = fopen(localFilePath, "rb");

    res = curl_global_init(CURL_GLOBAL_ALL);
    if(CURLE_OK != res)
    {
        return LIBCURL_RET_FAIL;
    }

    curl = curl_easy_init();
    if(curl) 
    {
        curl_easy_setopt(curl, CURLOPT_USERPWD, userPwd); 
        curl_easy_setopt(curl, CURLOPT_URL, ftpAddress);

        curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
        //curl_easy_setopt(curl, CURLOPT_PUT, 1L);
        curl_easy_setopt(curl, CURLOPT_READDATA, fp);
        curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)fsize);

        res = curl_easy_perform(curl);        
        if(CURLE_OK != res)
        {
            curl_easy_cleanup(curl);
            return LIBCURL_RET_FAIL;
        }

        if(fp)
            fclose(fp);

        curl_easy_cleanup(curl);
        curl_global_cleanup();
    }

    return LIBCURL_RET_OK;
}
  • ftp 下载
static size_t libcurl_ftp_download_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
    FILE *fp = (FILE *)stream;

    return fwrite(ptr, size, nmemb, fp); 
}

INT32 libcurl_ftp_download_file(const CHAR * ftpAddress, const CHAR * userPwd, const CHAR * fileSavePath)
{
    CURL *curl;
    CURLcode res;

    FILE *fp = fopen(fileSavePath, "w+");
    if(NULL == fp)        
    {
        printf("Open file error
");
        return LIBCURL_RET_FAIL;            
    }

    res = curl_global_init(CURL_GLOBAL_ALL);
    if(CURLE_OK != res)
    {
        return LIBCURL_RET_FAIL;
    }

    curl = curl_easy_init();
    if(curl) 
    {
        curl_easy_setopt(curl, CURLOPT_USERPWD, userPwd); 
        curl_easy_setopt(curl, CURLOPT_URL, ftpAddress);

        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, libcurl_ftp_download_callback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);

        res = curl_easy_perform(curl);        
        if(CURLE_OK != res)
        {
            curl_easy_cleanup(curl);
            return LIBCURL_RET_FAIL;
        }

        if(fp)
            fclose(fp);

        curl_easy_cleanup(curl);
        curl_global_cleanup();
    }

    return LIBCURL_RET_OK;
}
  • 保存下载内容到buffer中
struct MemoryStruct {
    CHAR *memory;
    size_t size;
};

struct MemoryStruct chunk;

static size_t curl_http_write_memory_cb(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  mem->memory = realloc(mem->memory, mem->size + realsize + 1);
  if (mem->memory == NULL) {
    /* out of memory! */
    printf("not enough memory (realloc returned NULL)
");
    exit(EXIT_FAILURE);
  }

  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;

  return realsize;
}

INT32 curl_http_get_page(const CHAR * url)
{
    CURL *curl;
    CURLcode res;

    chunk.memory = malloc(1);  /* will be grown as needed by the realloc above */
    chunk.size = 0;    /* no data at this point */

    res = curl_global_init(CURL_GLOBAL_ALL);
    if(CURLE_OK != res)
    {
        return CURL_RET_FAIL;
    }

    curl = curl_easy_init();
    if(curl) 
    {        
        curl_easy_setopt(curl, CURLOPT_URL, url);       
        curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, curl_http_write_memory_cb); 
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);


        curl_easy_perform(curl);
        curl_easy_cleanup(curl);
    }    

    return CURL_RET_OK;
}

参考资料

  1. 百度百科libcurl
  2. libcurl官网
  3. curl_easy_setopt说明文档
  4. curl_easy_getinfo说明文档
  5. 最全的libcurl库资源整理
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。