Libcurl的初步实现tfp上传下载功能


该学习笔记的目标是利用libcurl实现ftp文件上传和下载功能

一、Libcurlde的简介

Libcurl是一个免费的并且易于使用的利用url进行文件传输的库。, libcurl当前支持DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP,LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet and TFTP协议。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传, HTTP基本表单上传,代理,cookies,和用户认证。

Libcurl是一个轻量级的库,编译后能够运行到多种平台,包括:Solaris, NetBSD, FreeBSD, OpenBSD, Darwin, HPUX, IRIX, AIX, Tru64,Linux, UnixWare, HURD, Windows, Amiga, OS/2, BeOs, Mac OS X, Ultrix, QNX,OpenVMS, RISC OS, Novell NetWare, DOS 等

 

二、libcurl的接口

    Libcurl分为简单和复杂的接口。简单的接口是一个同步的,高效的,快速的,这种借口主要用于文件传输。大量的应用程序都使用这种方式。而复杂的姐姐偶是一个异步的,在这里不做过多研究

 

三、libcurl简单的接口工作流程

1、使用libcurl中的curl_easy_init()来初始化一个简单的文件传输会话并且获取到一个handle

2、通过使用curl_easy_setopt()来设置所有的选项参数,在这些参数中最重要的就是URL,同时你也极有可能需要设置一些回调函数,这些回调函数将会在条件符合的情况下被调用。

3、当上面的工作都做完了的时候,就可以使用curl_easy_perform()通知libcurl进行文件传输了,该函数在整个传输过程完成或者失败的时候才会返回一个值。

4、当你执行了第3步之后,你可以使用curl_easy_getinfo()来获取传输的信息

5、最后,你同样可以使用curl_easy_cleanup()来结束本次文件会话

下面针对这五个步骤,编写一个实例进行测试

 

四、部分功能函数的介绍

1、CURL *curl_easy_init( );

该函数必须首先调用,将会返回一个CURL*类型的handle.并且该函数将会和curl_easy_cleanup()一起配合使用。加入初始化出错的话,该函数将会返回一个NULL;

2、void curl_easy_cleanup(CURL *handle)

该函数一定是最后被调用的,他的参数应该是curl_easy_init的返回值;

3、CURLcode curl_easy_setopt(CURL*handle, CURLoption option, parameter);

该函数从名字上看就知道是设置一些参数的,通过设置不同的参数,将会改变libcurl的功能作用,这个需要仔细阅读指导文档,一旦设置方式不恰当,导致的错误将是致命的。

具体参数的使用方式在这个网址上描述的很详细

http://curl.haxx.se/libcurl/c/curl_easy_setopt.html

4、CURLcode curl_easy_perform(CURL * easy_handle);

像我们刚才提到的那样,这个函数应该是在init和setopt之后使用的,这个函数一旦执行,将会通知libcurl执行我们之前设置的所有方法,值得注意的是,当一个handle被加入到一个multi handle中之后,该参数handle将不能被函数perform调用

五、实例演示

1、下面来看一个简单的实例:

#include<stdio.h>
#include<curl/curl.h>
int main(int argc,char** argv)
{
    CURL *pCurlHandle = NULL;
    CURLcode errorCode = 0;
    /*1. 初始化一个pCurlHandle*/
    pCurlHandle = curl_easy_init();
 
    if( pCurlHandle )
    {
        /*2. 设置pCurlHandle的URL*/
        curl_easy_setopt( pCurlHandle,CURLOPT_URL, "http://blog.csdn.net/jxnu_xiaobing" );
        /*3. 因为上述网址已被重定向了,所以设置为CURLOPT_FOLLOWLOCATION*/
        curl_easy_setopt( pCurlHandle,CURLOPT_FOLLOWLOCATION, 1L );
        /*4. 开始执行上述opt*/
        errorCode = curl_easy_perform(pCurlHandle );
        if( errorCode != CURLE_OK )
        {
                printf("curl_easy_perform()  failed \n ");
        }
    }
    else
    {
        printf(" curl_easy_init()  failed \n ");
    }
    /*5. 最后关闭pCurlHandle*/
    curl_easy_cleanup( pCurlHandle );
    return 0;
}


2、上述的例子比较简单就是一个访问网页的例子,下面继续学习一个ftp上传的例子

#include<stdio.h>
#include<string.h>
#include<curl/curl.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<unistd.h>
 
#defineLOCAL_FILE     "/tmp/xiaobing.txt"
#defineREMOTE_URL     "ftp://172.30.26.247:21/xiaobing.txt" 
 
 
static size_tread_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
  curl_off_t nread;
  /* in real-world cases, this would probablyget this data differently
     as this fread() stuff is exactly what thelibrary already would do
     by default internally */
  size_t retcode = fread(ptr, size, nmemb,(FILE*)stream);
 
  nread = (curl_off_t)retcode;
 
  fprintf(stderr, "*** We read %"CURL_FORMAT_CURL_OFF_T
          " bytes from file\n",nread);
  return retcode;
}
 
int main(int argc,char **argv)
{
  CURL *pCurlhandle;
  CURLcode res;
  FILE *hd_src;
  struct stat file_info;
  curl_off_t fsize;
 
 
  /*1. 获取待上传文件的大小 */
  if(stat(LOCAL_FILE, &file_info)) {
    printf("Couldnt open '%s': %s\n",LOCAL_FILE, strerror(errno));
    return 1;
  }
  fsize = (curl_off_t)file_info.st_size;
 
  printf("Local file size: %"CURL_FORMAT_CURL_OFF_T " bytes.\n", fsize);
 
  /*2. 获取待上传文件的描述符 */
  hd_src = fopen(LOCAL_FILE, "rb");
 
  /*3. 初始化所有可能的调用*/
  curl_global_init(CURL_GLOBAL_ALL);
 
  /*4. 创建一个curlhandle*/
  pCurlhandle = curl_easy_init();
  if(curl)
    {
 
      /*5.设置一个回调函数 */
     curl_easy_setopt(pCurlhandle, CURLOPT_READFUNCTION, read_callback);
   
      /*6.使能上传标志位 */
     curl_easy_setopt(pCurlhandle, CURLOPT_UPLOAD, 1L);
   
      /*7.指定ftp服务器的url */
     curl_easy_setopt(pCurlhandle,CURLOPT_URL, REMOTE_URL);
   
      /*8.指定需要上传的文件 */
     curl_easy_setopt(pCurlhandle, CURLOPT_READDATA, hd_src);
   
      /*9.设置待上传文件的大小,这个大小是上面获取到的注意:当参数
      为CURLOPT_INFILESIZE_LARGE的时候,size类型应该是curl_off_t的,
      当参数为CURLOPT_INFILESIZE的时候size应该是long类型的*/
     curl_easy_setopt(pCurlhandle, CURLOPT_INFILESIZE_LARGE,
                       (curl_off_t)fsize);
   
     /*10. 开始执行我们上述设定的方法*/
      res= curl_easy_perform(pCurlhandle);
     /*11. 检查是否执行成功 */
     if(res != CURLE_OK)
       fprintf(stderr, "curl_easy_perform() failed: %s\n",
               curl_easy_strerror(res));
 
    /*12. 关闭pCurlhandle*/
     curl_easy_cleanup(pCurlhandle);
    }
  fclose(hd_src); /* close the local file */
  /*13. 清除所有可能的调用*/
  curl_global_cleanup();
  return 0;
}

上述程序就能够实现ftp上传文件


3、最后来看一个tfp下载的实例:

/*************************************************************************************
 *  * 文件名:              TfpcurlDownload.c
 *  * 功能:                curl测试程序
 *  * 作者:                http://blog.csdn.net/King_BingGe
 *  * 创建时间:            2014年09月29号 
 *  * 最后修改时间:				 2014年09月29号
 *  * 详细:                无
 *  **************************************************************************************/
#include <stdio.h>
#include <string.h>
#include <curl/curl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>

#define REMOTE_URL      "ftp://172.30.26.247:21/xiao.txt"  

typedef struct Ftpfile {
  const char *filename;
  FILE *stream;
}Cftpfile;

static size_t write_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
  Cftpfile *out = (Cftpfile*)stream;
  if( out && !out->stream )
  {
        out->stream = fopen(out->filename, "wb");
        if(!out->stream)
        {
                printf("write_callback failed \n ");
                return -1;
        }
  }
  return fwrite(ptr, size, nmemb, out->stream);
}


int main(int argc, char **argv)
{
  CURL *pCurlhandle;
  CURLcode res;
  curl_off_t fsize;
 
  Cftpfile ftpfile = {
  	"/tmp/xiaoxiao.txt"	,
    NULL
  };

  /*3. 初始化所有可能的调用*/
  curl_global_init(CURL_GLOBAL_ALL);

  /*4. 创建一个curlhandle*/
  pCurlhandle = curl_easy_init();
  if(pCurlhandle)
  {
    /*5. 设置一个回调函数 */
    curl_easy_setopt(pCurlhandle, CURLOPT_WRITEFUNCTION, write_callback );
    /*7. 指定ftp服务器的url */
    curl_easy_setopt(pCurlhandle,CURLOPT_URL, REMOTE_URL);

    /*8. 指定需要上传的文件 */
    curl_easy_setopt(pCurlhandle, CURLOPT_USERPWD, "cdn_ftp:123456");

    /*9. 指定需要上传的文件 */
    curl_easy_setopt(pCurlhandle, CURLOPT_WRITEDATA, &ftpfile );

    /*10. 设置待下载文件的大小,这个大小是上面获取到的注意:当参数
    为CURLOPT_INFILESIZE_LARGE的时候,size类型应该是curl_off_t的,
    当参数为CURLOPT_INFILESIZE的时候size应该是long类型的*/
    curl_easy_setopt(pCurlhandle, CURLOPT_INFILESIZE_LARGE,
                     (curl_off_t)fsize);
    /*11. 开始执行我们上述设定的方法 */
    res = curl_easy_perform(pCurlhandle);
    /*12. 检查是否执行成功 */
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));

    /*13. 关闭pCurlhandle*/
    curl_easy_cleanup(pCurlhandle);
  }
  else
  {
        printf("curl_easy_init failed \n ");
  }
  /*14. 清除所有可能的调用*/
  curl_global_cleanup();
  return 0;
}




  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
libcurl提供了一些选项和回调函数,可以用于实现暂停和继续下载。具体来说,可以通过设置CURLOPT_WRITEFUNCTION选项和CURLOPT_WRITEDATA选项来控制接收到的数据的处理方式,然后在回调函数中添加暂停和继续下载的逻辑。 例如,可以设置一个全局变量或者结构体来控制下载的状态,并在回调函数中检查该变量的值来决定是否继续处理数据。当需要暂停下载时,将该变量的值设置为一个特定的标记,然后在回调函数中判断该标记是否已被设置。如果已经设置,就返回一个非零值,告诉libcurl停止输数据,直到该变量被重新设置为其他值。当需要继续下载时,将该变量的值设置为其他值,再次调用curl_easy_perform()函数即可。 示例代码如下: ``` int transfer_paused = 0; FILE *fp = NULL; size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata) { // check if transfer is paused if (transfer_paused) { return CURL_WRITEFUNC_PAUSE; } // write received data to file fwrite(ptr, size, nmemb, fp); return size * nmemb; } // pause transfer transfer_paused = 1; // resume transfer transfer_paused = 0; curl_easy_perform(curl); ``` 在这个示例中,当transfer_paused变量被设置为1时,回调函数write_callback()会返回CURL_WRITEFUNC_PAUSE来暂停下载。当该变量被设置为0时,回调函数将继续将数据写入文件。可以根据需要在其他地方设置和清除该变量的值,并在下载暂停和继续时调用curl_easy_perform()函数。另外,需要在设置CURLOPT_WRITEFUNCTION选项和CURLOPT_WRITEDATA选项之前,打开或创建一个文件,并将文件指针递给CURLOPT_WRITEDATA选项。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值