• 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 
     ");
            }
        }
        else
        {
            printf(" curl_easy_init()  failed 
     ");
        }
        /*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
    ",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
    ",LOCAL_FILE, strerror(errno));
        return 1;
      }
      fsize = (curl_off_t)file_info.st_size;
     
      printf("Local file size: %"CURL_FORMAT_CURL_OFF_T " bytes.
    ", 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.指定ftpserver的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
    ",
                   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 
     ");
                    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. 指定ftpserver的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
    ",
                  curl_easy_strerror(res));
    
        /*13. 关闭pCurlhandle*/
        curl_easy_cleanup(pCurlhandle);
      }
      else
      {
            printf("curl_easy_init failed 
     ");
      }
      /*14. 清除全部可能的调用*/
      curl_global_cleanup();
      return 0;
    }




  • 相关阅读:
    [zz][openstack swift]0 swift介绍
    [zz]/usr、/var和/etc目录
    [zz]使用 watchdog 构建高可用性的 Linux 系统及应用
    [zz]sheep dog的readme
    [zz] Consistent Hashing Ring
    [zz]为什么这些死脑筋们在用 VI ?
    libvirt 网络
    [zz]libcapng
    libvirt 创建的文件
    电商购物网站如何调用第三方支付平台(支付宝,财付通,盛付通等)
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/6812344.html
Copyright © 2020-2023  润新知