libcurl使用简介

一. 是一个为网络客户端提供数据传输功能的函数库,支持HTTP,HTTPS,FTP,TELNET等协议和各种SSL安全认证。
  libcurl是开源项目,可以在其官网下载:http://curl.haxx.se/libcurl/

二. 基于libcurl的程序里主要用回调函数形式完全成任务,用户在启动传输前先设好各类参数和回调函数,当条件满足时libcurl再调用用户的回调实现特定功能。libcurl工作模式主要有两种:简单接口和多线程接口。简单接口可以实现同步、快速的文件传输;多线程接口则可生成多个连接线程以异步方式进行文件传输。

三. 使用简单接口的工作流程

  1. 调用curl_global_init()初始化libcurl
  2. 调用curl_easy_init()函数得到easyinterface型指针
  3. 调用curl_easy_setopt设置传输选项
  4. 根据curl_easy_setopt设置的传输选项,实现回调函数以完成用户特定任务
  5. 调用curl_easy_perform()函数完成传输任务
  6. 调用curl_easy_cleanup()释放内存
    在整过过程中设置curl_easy_setopt()参数是最关键的,几乎所有的libcurl程序都要使用它。

四. 主要函数

  1. CURL codecurl_global_init(longflags);
    描述:
    这个函数只能用一次。(其实在调用curl_global_cleanup函数后仍然可再用)
    如果这个函数在curl_easy_init函数调用时还没调用,它讲由libcurl库自动完成。
    参数:flags
    CURL_GLOBAL_ALL //初始化所有的可能的调用。
    CURL_GLOBAL_SSL //初始化支持安全套接字层。
    CURL_GLOBAL_WIN32 //初始化win32套接字库。
    CURL_GLOBAL_NOTHING //没有额外的初始化。

  2. void curl_global_cleanup(void);
    描述:在结束libcurl使用的时候,用来对curl_global_init做的工作清理。类似于close的函数。

  3. char * curl_version( );
    描述:打印当前libcurl库的版本。

  4. CURL * curl_easy_init();
    描述:
    curl_easy_init用来初始化一个CURL的指针(有些像返回FILE类型的指针一样).相应的在调用结束时要用curl_easy_cleanup函数清理.
    一般curl_easy_init意味着一个会话的开始.它的返回值一般都用在easy系列的函数中.

  5. void curl_easy_cleanup(CURL*handle);
    描述:
    这个调用用来结束一个会话.与curl_easy_init配合着用.
    参数:
    CURL类型的指针.

  6. CURL code curl_easy_setopt(CURL *handle, CURLoption option,parameter);
    描述:
    这个函数最重要了.几乎所有的curl程序都要频繁的使用它.它告诉curl库.程序将有如何的行为.比如要查看一个网页的html代码等.(这个函数有些像ioctl函数)
    参数:
    (1)CURL类型的指针
    (2)各种CURLoption类型的选项.(都在curl.h库里有定义,man也可以查看到)
    (3)parameter 这个参数既可以是个函数的指针,也可以是某个对象的指针,也可以是个long型的变量.它用什么这取决于第二个参数.
    CURLoption这个参数的取值很多.具体的可以查看man手册.

  7. CURL code curl_easy_perform(CURL *handle);
    描述:
    这个函数在初始化CURL类型的指针以及curl_easy_setopt完成后调用.就像字面的意思所说perform就像是个舞台.让我们设置的option运作起来.
    参数:
    CURL类型的指针.

五. curl_easy_setopt函数介绍

本节主要介绍curl_easy_setopt中跟http相关的参数。注意本节的阐述都是以libcurl作为主体,其它为客体来阐述的。
  1. CURLOPT_URL
    设置访问URL

  2. CURLOPT_WRITEFUNCTION,CURLOPT_WRITEDATA
    回调函数原型为:size_t function( void *ptr, size_t size, size_t nmemb, void *stream);
    函数将在libcurl接收到数据后被调用,因此函数多做数据保存的功能,如处理下载文件。CURLOPT_WRITEDATA用于表明CURLOPT_WRITEFUNCTION函数中的stream指针的来源。

  3. CURLOPT_HEADERFUNCTION,CURLOPT_HEADERDATA
    回调函数原型为size_t function( void *ptr, size_t size,size_t nmemb, void *stream);
    libcurl一旦接收到http头部数据后将调用该函数。CURLOPT_WRITEDATA传递指针给libcurl,该指针表明CURLOPT_HEADERFUNCTION函数的stream指针的来源。

  4. CURLOPT_READFUNCTION,CURLOPT_READDATA
    libCurl需要读取数据传递给远程主机时将调用CURLOPT_READFUNCTION指定的函数.
    函数原型是:size_t function(void *ptr, size_t size, size_t nmemb,void *stream);
    CURLOPT_READDATA 表明CURLOPT_READFUNCTION函数原型中的stream指针来源。

  5. CURLOPT_NOPROGRESS,CURLOPT_PROGRESSFUNCTION,CURLOPT_PROGRESSDATA
    跟数据传输进度相关的参数。CURLOPT_PROGRESSFUNCTION指定的函数正常情况下每秒被libcurl调用一次,为了使CURLOPT_PROGRESSFUNCTION被调用,CURLOPT_NOPROGRESS必须被设置为false,CURLOPT_PROGRESSDATA指定的参数将作为CURLOPT_PROGRESSFUNCTION指定函数的第一个参数

  6. CURLOPT_TIMEOUT,CURLOPT_CONNECTIONTIMEOUT:
    CURLOPT_TIMEOUT由于设置传输时间,CURLOPT_CONNECTIONTIMEOUT设置连接等待时间

  7. CURLOPT_FOLLOWLOCATION
    设置重定位URL

  8. CURLOPT_RANGE,CURLOPT_RESUME_FROM:
    断点续传相关设置。CURLOPT_RANGE指定char*参数传递给libcurl,用于指明http域的RANGE头域,例如:
    表示头500个字节:bytes=0-499
    表示第二个500字节:bytes=500-999
    表示最后500个字节:bytes=-500
    表示500字节以后的范围:bytes=500-
    第一个和最后一个字节:bytes=0-0,-1
    同时指定几个范围:bytes=500-600,601-999
    CURLOPT_RESUME_FROM传递一个long参数给libcurl,指定你希望开始传递的偏移量。

附:
CURLOPT_HEADER:设为1,则在返回的内容里包含http header;
CURLOPT_FOLLOWLOCATION:设为0,则不会自动301,302跳转;
*CURLOPT_INFILESIZE: 当你上传一个文件到远程站点,这个选项告诉PHP你上传文件的大小。
*CURLOPT_VERBOSE: 如果你想CURL报告每一件意外的事情,设置这个选项为一个非零值。
*CURLOPT_HEADER: 如果你想把一个头包含在输出中,设置这个选项为一个非零值。
*CURLOPT_NOPROGRESS: 如果你不会PHP为CURL传输显示一个进程条,设置这个选项为一个非零值。

注意:PHP自动设置这个选项为非零值,你应该仅仅为了调试的目的来改变这个选项。

*CURLOPT_NOBODY: 如果你不想在输出中包含body部分,设置这个选项为一个非零值。
*CURLOPT_FAILONERROR: 如果你想让PHP在发生错误(HTTP代码返回大于等于300)时,不显示,设置这个选项为一人非零值。默认行为是返回一个正常页,忽略代码。
*CURLOPT_UPLOAD: 如果你想让PHP为上传做准备,设置这个选项为一个非零值。
*CURLOPT_POST: 如果你想PHP去做一个正规的HTTP POST,设置这个选项为一个非零值。这个POST是普通的 application/x-www-from-urlencoded 类型,多数被HTML表单使用。
*CURLOPT_FTPLISTONLY: 设置这个选项为非零值,PHP将列出FTP的目录名列表。
*CURLOPT_FTPAPPEND: 设置这个选项为一个非零值,PHP将应用远程文件代替覆盖它。
*CURLOPT_NETRC: 设置这个选项为一个非零值,PHP将在你的 ~./netrc 文件中查找你要建立连接的远程站点的用户名及密码。
*CURLOPT_FOLLOWLOCATION: 设置这个选项为一个非零值(象 “Location: “)的头,服务器会把它当做HTTP头的一部分发送(注意这是递归的,PHP将发送形如 “Location: “的头)。
*CURLOPT_PUT: 设置这个选项为一个非零值去用HTTP上传一个文件。要上传这个文件必须设置CURLOPT_INFILE和CURLOPT_INFILESIZE选项.
*CURLOPT_MUTE: 设置这个选项为一个非零值,PHP对于CURL函数将完全沉默。
*CURLOPT_TIMEOUT: 设置一个长整形数,作为最大延续多少秒。
*CURLOPT_LOW_SPEED_LIMIT: 设置一个长整形数,控制传送多少字节。
*CURLOPT_LOW_SPEED_TIME: 设置一个长整形数,控制多少秒传送CURLOPT_LOW_SPEED_LIMIT规定的字节数。
*CURLOPT_RESUME_FROM: 传递一个包含字节偏移地址的长整形参数,(你想转移到的开始表单)。
*CURLOPT_SSLVERSION: 传递一个包含SSL版本的长参数。默认PHP将被它自己努力的确定,在更多的安全中你必须手工设置。
*CURLOPT_TIMECONDITION: 传递一个长参数,指定怎么处理CURLOPT_TIMEVALUE参数。你可以设置这个参数为TIMECOND_IFMODSINCE 或 TIMECOND_ISUNMODSINCE。这仅用于HTTP。
*CURLOPT_TIMEVALUE: 传递一个从1970-1-1开始到现在的秒数。这个时间将被CURLOPT_TIMEVALUE选项作为指定值使用,或被默认TIMECOND_IFMODSINCE使用。

下列选项的值将被作为字符串:

*CURLOPT_URL: 这是你想用PHP取回的URL地址。你也可以在用curl_init()函数初始化时设置这个选项。
*CURLOPT_USERPWD: 传递一个形如[username]:[password]风格的字符串,作用PHP去连接。
*CURLOPT_PROXYUSERPWD: 传递一个形如[username]:[password] 格式的字符串去连接HTTP代理。
*CURLOPT_RANGE: 传递一个你想指定的范围。它应该是”X-Y”格式,X或Y是被除外的。HTTP传送同样支持几个间隔,用逗句来分隔(X-Y,N-M)。
*CURLOPT_POSTFIELDS: 传递一个作为HTTP “POST”操作的所有数据的字符串。
*CURLOPT_REFERER: 在HTTP请求中包含一个”referer”头的字符串。
*CURLOPT_USERAGENT: 在HTTP请求中包含一个”user-agent”头的字符串。
*CURLOPT_FTPPORT: 传递一个包含被ftp “POST”指令使用的IP地址。这个POST指令告诉远程服务器去连接我们指定的IP地址。这个字符串可以是一个IP地址,一个主机名,一个网络界面名(在UNIX下),或是‘-’(使用系统默认IP地址)。
*CURLOPT_COOKIE: 传递一个包含HTTP cookie的头连接。
*CURLOPT_SSLCERT: 传递一个包含PEM格式证书的字符串。
*CURLOPT_SSLCERTPASSWD: 传递一个包含使用CURLOPT_SSLCERT证书必需的密码。
*CURLOPT_COOKIEFILE: 传递一个包含cookie数据的文件的名字的字符串。这个cookie文件可以是Netscape格式,或是堆存在文件中的HTTP风格的头。
*CURLOPT_CUSTOMREQUEST: 当进行HTTP请求时,传递一个字符被GET或HEAD使用。为进行DELETE或其它操作是有益的,更Pass a string to be used instead of GET or HEAD when doing an HTTP request. This is useful for doing or another, more obscure, HTTP request.

注意: 在确认你的服务器支持命令先不要去这样做。

下列的选项要求一个文件描述(通过使用fopen()函数获得):
*CURLOPT_FILE: 这个文件将是你放置传送的输出文件,默认是STDOUT.
*CURLOPT_INFILE: 这个文件是你传送过来的输入文件。
*CURLOPT_WRITEHEADER: 这个文件写有你输出的头部分。
*CURLOPT_STDERR: 这个文件写有错误而不是stderr。

六. curl_easy_perform函数说明(error状态码)

该函数完成curl_easy_setopt指定的所有选项,本节重点介绍curl_easy_perform的返回值。返回0意味一切ok,非0代表错误发生。主要错误码说明:
  1. CURLE_OK
    任务完成一切都好

  2. CURLE_UNSUPPORTED_PROTOCOL
    不支持的协议,由URL的头部指定

  3. CURLE_COULDNT_CONNECT
    不能连接到remote主机或者代理

  4. CURLE_REMOTE_ACCESS_DENIED
    访问被拒绝

  5. CURLE_HTTP_RETURNED_ERROR
    Http返回错误

  6. CURLE_READ_ERROR
    读本地文件错误

七. 获取html网页

#include<stdio.h>
#include<curl/curl.h>
#include<stdlib.h>

intmain(int argc, char *argv[])
{
    CURL*curl;             //定义CURL类型的指针
    CURLcoderes;           //定义CURLcode类型的变量,保存返回状态码

    if(argc!=2)
    {
        printf("Usage: file <url>;\n");
        exit(1);
    }

    curl= curl_easy_init();       //初始化一个CURL类型的指针

    if(curl!=NULL)
    {
        //设置curl选项.其中CURLOPT_URL是让用户指定url.argv[1]中存放的命令行传进来的网址
        curl_easy_setopt(curl,CURLOPT_URL, argv[1]);       
        //调用curl_easy_perform执行我们的设置.并进行相关的操作.在这里只在屏幕上显示出来.
        res= curl_easy_perform(curl);
        //清除curl操作.
        curl_easy_cleanup(curl);
    }

    return0;
}

编译gcc get_http.c -o get_http –lcurl
./get_http www.baidu.com

八. 网页下载保存实例

//采用CURLOPT_WRITEFUNCTION实现网页下载保存功能

#include<stdio.h>;
#include<stdlib.h>;
#include<unistd.h>;
#include<curl/curl.h>;
#include<curl/types.h>;
#include<curl/easy.h>;

FILE*fp;  //定义FILE类型指针

//这个函数是为了符合CURLOPT_WRITEFUNCTION而构造的
//完成数据保存功能
size_twrite_data(void *ptr, size_t size, size_t nmemb, void *stream) 
{
    intwritten = fwrite(ptr, size, nmemb, (FILE *)fp);
    returnwritten;
}

int main(int argc, char *argv[])
{
    CURL* curl;

    curl_global_init(CURL_GLOBAL_ALL); 

    curl=curl_easy_init();

    curl_easy_setopt(curl,CURLOPT_URL, argv[1]); 

    if((fp=fopen(argv[2],"w"))==NULL)
    {
        curl_easy_cleanup(curl);
        exit(1);
    }

    //CURLOPT_WRITEFUNCTION将后继的动作交给write_data函数处理
    curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION, write_data); 

    curl_easy_perform(curl);

    curl_easy_cleanup(curl);

    exit(0);
}

编译gcc save_http.c -o save_http –lcurl
./save_http www.baidu.com /tmp/baidu

九. 进度条实例显示文件下载进度

//采用CURLOPT_NOPROGRESS,CURLOPT_PROGRESSFUNCTION   CURLOPT_PROGRESSDATA 实现文件传输进度提示功能
//函数采用了gtk库,故编译时需指定gtk库
//函数启动专门的线程用于显示gtk进度条bar

#include<stdio.h>
#include<gtk/gtk.h>
#include<curl/curl.h>
#include<curl/types.h> /* new for v7 */
#include<curl/easy.h>  /* new for v7 */

GtkWidget*Bar;

//这个函数是为了符合CURLOPT_WRITEFUNCTION而构造的
//完成数据保存功能
size_t my_write_func(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
    returnfwrite(ptr, size, nmemb, stream);
}

//这个函数是为了符合CURLOPT_READFUNCTION而构造的
//数据上传时使用
size_t my_read_func(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
    returnfread(ptr, size, nmemb, stream);
}

//这个函数是为了符合CURLOPT_PROGRESSFUNCTION而构造的
//显示文件传输进度,t代表文件大小,d代表传输已经完成部分
int my_progress_func(GtkWidget *bar,
                    doublet, /* dltotal */
                    doubled, /* dlnow */
                    doubleultotal,
                    doubleulnow)
{
    /* printf("%d / %d (%g %%)\n", d, t, d*100.0/t);*/
    gdk_threads_enter();
    gtk_progress_set_value(GTK_PROGRESS(bar),d*100.0/t);
    gdk_threads_leave();

    return 0;
}

void* my_thread(void *ptr)
{
    CURL*curl;
    CURLcoderes;
    FILE*outfile;
    gchar*url = ptr;

    curl= curl_easy_init();

    if(curl)
    {
        outfile= fopen("test.curl", "w");

        curl_easy_setopt(curl,CURLOPT_URL, url);
        curl_easy_setopt(curl,CURLOPT_WRITEDATA, outfile);
        curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION, my_write_func);
        curl_easy_setopt(curl,CURLOPT_READFUNCTION, my_read_func);
        curl_easy_setopt(curl,CURLOPT_NOPROGRESS, 0L);
        curl_easy_setopt(curl,CURLOPT_PROGRESSFUNCTION, my_progress_func);
        curl_easy_setopt(curl,CURLOPT_PROGRESSDATA, Bar);

        res= curl_easy_perform(curl);

        fclose(outfile);

        /*always cleanup */
        curl_easy_cleanup(curl);
  }

  returnNULL;
}

int main(int argc, char **argv)
{
    GtkWidget *Window, *Frame, *Frame2;
    GtkAdjustment *adj;

    /*Must initialize libcurl before any threads are started */
    curl_global_init(CURL_GLOBAL_ALL);

    /*Init thread */
    g_thread_init(NULL);

    gtk_init(&argc,&argv);

    Window= gtk_window_new(GTK_WINDOW_TOPLEVEL);
    Frame= gtk_frame_new(NULL);
    gtk_frame_set_shadow_type(GTK_FRAME(Frame),GTK_SHADOW_OUT);
    gtk_container_add(GTK_CONTAINER(Window),Frame);

    Frame2= gtk_frame_new(NULL);
    gtk_frame_set_shadow_type(GTK_FRAME(Frame2),GTK_SHADOW_IN);
    gtk_container_add(GTK_CONTAINER(Frame),Frame2);
    gtk_container_set_border_width(GTK_CONTAINER(Frame2),5);
    adj= (GtkAdjustment*)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
    Bar= gtk_progress_bar_new_with_adjustment(adj);
    gtk_container_add(GTK_CONTAINER(Frame2),Bar);
    gtk_widget_show_all(Window);

    if(!g_thread_create(&my_thread, argv[1], FALSE, NULL) != 0)
        g_warning("can'tcreate the thread");

    gdk_threads_enter();

    gtk_main();

    gdk_threads_leave();

    return 0;
}

编译exportPKG_CONFIG_PATH=/usr/lib/pkgconfig/
gcc progress.c –o progress pkg-config --libs –cflags gtk+-2..0 -lcurl –lgthread-2.0
./progress http://software.sky-union.cn/index.asp

十. 断点续传实例

//采用CURLOPT_RESUME_FROM_LARGE实现文件断点续传功能
#include<stdlib.h>
#include<stdio.h>
#include<sys/stat.h>
#include<curl/curl.h>

//这个函数为CURLOPT_HEADERFUNCTION参数构造
/*从http头部获取文件size*/
size_tgetcontentlengthfunc(void *ptr, size_t size, size_t nmemb, void*stream) 
{
    int r;
    longlen = 0;

    /*_snscanf() is Win32 specific */
    //r = _snscanf(ptr, size * nmemb, "Content-Length: %ld\n",&len);
     r= sscanf(ptr, "Content-Length: %ld\n", &len);
    if(r) /* Microsoft: we don't read the specs */
        *((long*) stream) = len;

    returnsize * nmemb;
}

/*保存下载文件*/
size_t wirtefunc(void *ptr, size_t size, size_t nmemb, void *stream)
{
    returnfwrite(ptr, size, nmemb, stream);
}

/*读取上传文件*/
size_treadfunc(void *ptr, size_t size, size_t nmemb, void *stream)
{
    FILE*f = stream;
    size_tn;

    if(ferror(f))
        returnCURL_READFUNC_ABORT;

    n= fread(ptr, size, nmemb, f) * size;

    return n;
}

//下载或者上传文件函数
int download(CURL *curlhandle, const char * remotepath, const char *localpath,
           longtimeout, long tries)
{
    FILE* f;
    curl_off_t local_file_len = -1 ;
    long filesize =0 ;
    CURLcoder = CURLE_GOT_NOTHING;
    int c;

    structstat file_info;
    intuse_resume = 0;

    /*得到本地文件大小*/
    //if(access(localpath,F_OK)==0)
    if(stat(localpath,&file_info) == 0)
    {
        local_file_len = file_info.st_size;
        use_resume = 1;
    }

    //采用追加方式打开文件,便于实现文件断点续传工作
    f= fopen(localpath, "ab+");
    if(f == NULL) 
    {
        perror(NULL);
        return 0;
    }

    //curl_easy_setopt(curlhandle,CURLOPT_UPLOAD, 1L);
    curl_easy_setopt(curlhandle,CURLOPT_URL, remotepath);
    curl_easy_setopt(curlhandle,CURLOPT_CONNECTTIMEOUT, timeout);  // 设置连接超时,单位秒

    //设置http头部处理函数
    curl_easy_setopt(curlhandle,CURLOPT_HEADERFUNCTION, getcontentlengthfunc);
    curl_easy_setopt(curlhandle,CURLOPT_HEADERDATA, &filesize);

    //设置文件续传的位置给libcurl
    curl_easy_setopt(curlhandle,CURLOPT_RESUME_FROM_LARGE, use_resume?local_file_len:0);
    curl_easy_setopt(curlhandle,CURLOPT_WRITEDATA, f);
    curl_easy_setopt(curlhandle,CURLOPT_WRITEFUNCTION, wirtefunc);
    //curl_easy_setopt(curlhandle,CURLOPT_READFUNCTION, readfunc);
    //curl_easy_setopt(curlhandle,CURLOPT_READDATA, f);
    curl_easy_setopt(curlhandle,CURLOPT_NOPROGRESS, 1L);
    curl_easy_setopt(curlhandle,CURLOPT_VERBOSE, 1L);
    r= curl_easy_perform(curlhandle);
    fclose(f);

    if(r == CURLE_OK)
        return 1;
    else
    {
        fprintf(stderr,"%s\n", curl_easy_strerror(r));
        return 0;
    }
}

int main(int c, char **argv) 
{
    CURL*curlhandle = NULL;
    curl_global_init(CURL_GLOBAL_ALL);
    curlhandle= curl_easy_init();

    //download(curlhandle,"ftp://user:pass@host/path/file", "C:\\file",0, 3);
    download(curlhandle, "http://software.sky-union.cn/index.asp","/work/index.asp",1,3);

    curl_easy_cleanup(curlhandle);

    curl_global_cleanup();

    return 0;
}

编译gcc resume.c -o resume –lcurl
./resume

十一. LibCurl调试实例

//采用CURLOPT_DEBUGFUNCTION参数实现libcurl调试功能
#include<stdio.h>
#include<curl/curl.h>

struct data 
{
    chartrace_ascii; /* 1 or 0 */
};

static void dump(const char *text,
          FILE*stream, unsigned char *ptr, size_t size,
          charnohex)
{
    size_t i;
    size_t c;
    unsigned int width = 0x10;

    if(nohex)
    {
        /*without the hex output, we can fit more on screen */
        width = 0x40;

        fprintf(stream,"%s, %zd bytes (0x%zx)\n", text, size, size);

        for(i=0;i<size; i+= width)
        {
            fprintf(stream,"%04zx: ", i);
            if(!nohex)
            {
                /*hex not disabled, show it */
                for(c= 0; c < width; c++)
                    if(i+c< size)
                        fprintf(stream,"%02x ", ptr[i+c]);
                    else
                        fputs("  ", stream);
                }

                for(c= 0; (c < width) && (i+c < size); c++) 
                {
                    /*check for 0D0A; if found, skip past and start a new line of output*/
                    if(nohex && (i+c+1 < size) && ptr[i+c]==0x0D &&ptr[i+c+1]==0x0A) 
                    i+=(c+2-width);
                    break;
                }

                fprintf(stream,"%c",
                    (ptr[i+c]>=0x20)&& (ptr[i+c]<0x80)?ptr[i+c]:'.');
                /*check again for 0D0A, to avoid an extra \n if it's at width */
                if(nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D &&ptr[i+c+2]==0x0A)
                {
                    i+=(c+3-width);
                    break;
                }
            }
            fputc('\n',stream); /* newline */
        }
    fflush(stream);
}

static int my_trace(CURL *handle, curl_infotype type,
            char*data, size_t size,
            void*userp)
{
  structdata *config = (struct data *)userp;
  constchar *text;
  (void)handle;/* prevent compiler warning */

  switch(type) 
  {
  caseCURLINFO_TEXT:
    fprintf(stderr,"== Info: %s", data);

  default:/* in case a new one is introduced to shock us */
    return 0;

  caseCURLINFO_HEADER_OUT:
    text= "=> Send header";
    break;

  caseCURLINFO_DATA_OUT:
    text= "=> Send data";
    break;

  caseCURLINFO_SSL_DATA_OUT:
    text= "=> Send SSL data";
    break;

  caseCURLINFO_HEADER_IN:
    text= "<= Recv header";
    break;

  caseCURLINFO_DATA_IN:
    text= "<= Recv data";
    break;

  caseCURLINFO_SSL_DATA_IN:
    text= "<= Recv SSL data";
    break;
  }

  dump(text,stderr, (unsigned char *)data, size, config->trace_ascii);
  return 0;
}

int main(void)
{
  CURL* curl;
  CURLcode res;
  struct data config;

  config.trace_ascii= 1; /* enable ascii tracing */
  ...
  }



  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值