栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

libcurl的使用(ftp-wildcard)——C++

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

libcurl的使用(ftp-wildcard)——C++

前言

之前未曾用过libcurl,只是在postman文档中见过http访问接口是通过libcurl实现的,这次看到同事用其实现的ftp,顿时觉得libcurl在通信中,还是挺万能的,所以我想学一下。

我查过资料后发现它真的支持很多协议:libcurl当前支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。还有,它是一个跨平台的网络协议库,在基于LibCurl的程序里,主要采用callback function (回调函数)的形式完成传输任务,用户在启动传输前设置好各类参数和回调函数,当满足条件时libcurl将调用用户的回调函数实现特定功能。

学习libcurl,其实最好看一下官方的文档:libcurl - programming tutorial

基础知识介绍

libcurl有两种工作模式:easy interface,此模式是同步,阻塞式的传输,单个传输;

multi interface,此模式是在单个线程同时进行多个传输,它有多线程的优点,但是有不需要承担多线程管理的责任,很是方便。大家可根据不同的需求,选取不同的模式。

easy模式的流程
  • curl_global_init(long flags) :libcurl初始化,在任何平台使用libcurl的方法之前,必须要用此函数进行先初始化。唯一的参数是为了设置如何初始化的,有以下几个值:默认CURL_GLOBAL_DEFAULT是CURL_GLOBAL_ALL,即初始化所有已知的全部子模块;CURL_GLOBAL_WIN32,只能在windows系统上使用,它会初始化win32 socket ;CURL_GLOBAL_SSL,它会初始化ssl库。
#define CURL_GLOBAL_SSL (1<<0)
#define CURL_GLOBAL_WIN32 (1<<1)
#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32)
#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL
  •  获取操作句柄。根据自己的需求,选用不同的模式,获取对应的句柄。
m_pHndCurlEasy = curl_easy_init();
  • 传输时,通过curl_easy_setopt设置基本参数,如url地址、http头、cookie信息、发送超时时间等,其中,CURLOPT_URL是必设的选项,格式如下。 第二个参数不同值决定设置不同的参数类型,具体可参考博客:curl库中curl_easy_setopt函数详解_I_O_fly的博客-CSDN博客_curl_easy_setopt
curl_easy_setopt(handle, CURLOPT_URL, "http://domain.com/");
  • 设置完成后,调用curl_easy_perform(CURL *curl)函数发送数据,我理解为“开始表演了!!”:基本配置已配置好,开始运转了;
  • 数据发送完毕后,调用curl_easy_cleanup清空句柄;
  • 不再使用libcurl后,调用curl_global_cleanup()做清理工作。也可以说一个curl_global_init对应一个curl_global_cleanup。
官方示例

官方示例的网址是:libcurl - source code examples

可以将官方示例下载下来,看看在各种场合的用法。

这里我贴一个ftp通配符下载文件的示例(ftp-wildcard),可以看出与我上方介绍的流程是一致的(easy模式)。

#include 
#include 

struct callback_data {
  FILE *output;
};

static long file_is_coming(struct curl_fileinfo *finfo,
                           struct callback_data *data,
                           int remains);

static long file_is_downloaded(struct callback_data *data);

static size_t write_it(char *buff, size_t size, size_t nmemb,
                       void *cb_data);

int main(int argc, char **argv)
{
  
  CURL *handle;

  
  struct callback_data data = { 0 };

  
  int rc = curl_global_init(CURL_GLOBAL_ALL);
  if(rc)
    return rc;

  
  handle = curl_easy_init();
  if(!handle) {
    curl_global_cleanup();
    return CURLE_OUT_OF_MEMORY;
  }

  
  curl_easy_setopt(handle, CURLOPT_WILDCARDMATCH, 1L);

  
  curl_easy_setopt(handle, CURLOPT_CHUNK_BGN_FUNCTION, file_is_coming);

  
  curl_easy_setopt(handle, CURLOPT_CHUNK_END_FUNCTION, file_is_downloaded);

  
  curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_it);

  
  curl_easy_setopt(handle, CURLOPT_CHUNK_DATA, &data);
  curl_easy_setopt(handle, CURLOPT_WRITEDATA, &data);

  

  
  if(argc == 2)
    curl_easy_setopt(handle, CURLOPT_URL, argv[1]);
  else
    curl_easy_setopt(handle, CURLOPT_URL, "ftp://example.com/test
  rc = curl_easy_perform(handle);

  curl_easy_cleanup(handle);
  curl_global_cleanup();
  return rc;
}

static long file_is_coming(struct curl_fileinfo *finfo,
                           struct callback_data *data,
                           int remains)
{
  printf("%3d %40s %10luB ", remains, finfo->filename,
         (unsigned long)finfo->size);

  switch(finfo->filetype) {
  case CURLFILETYPE_DIRECTORY:
    printf(" DIRn");
    break;
  case CURLFILETYPE_FILE:
    printf("FILE ");
    break;
  default:
    printf("OTHERn");
    break;
  }

  if(finfo->filetype == CURLFILETYPE_FILE) {
    
    if(finfo->size > 50) {
      printf("SKIPPEDn");
      return CURL_CHUNK_BGN_FUNC_SKIP;
    }

    data->output = fopen(finfo->filename, "wb");
    if(!data->output) {
      return CURL_CHUNK_BGN_FUNC_FAIL;
    }
  }

  return CURL_CHUNK_BGN_FUNC_OK;
}

static long file_is_downloaded(struct callback_data *data)
{
  if(data->output) {
    printf("DOWNLOADEDn");
    fclose(data->output);
    data->output = 0x0;
  }
  return CURL_CHUNK_END_FUNC_OK;
}

static size_t write_it(char *buff, size_t size, size_t nmemb,
                       void *cb_data)
{
  struct callback_data *data = cb_data;
  size_t written = 0;
  if(data->output)
    written = fwrite(buff, size, nmemb, data->output);
  else
    
    written = fwrite(buff, size, nmemb, stdout);
  return written;
}

结束语

easy interface是基本的,也是最简单的用法,后续如果有空的话,写一篇multi interface的。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/966000.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号