libcurl教程
- 格式:doc
- 大小:520.00 KB
- 文档页数:25
libcurl 源码编译Libcurl是一个开源的网络传输库,它支持多种协议,包括HTTP、FTP、SMTP等。
它的源码可以在官方网站上下载,也可以通过Git 仓库获取。
本文将介绍如何从源码编译libcurl。
我们需要下载libcurl的源码。
可以在官方网站上下载最新版本的源码,也可以通过Git仓库获取最新的开发版本。
下载完成后,我们需要解压源码包。
接下来,我们需要进入源码目录,执行configure脚本。
这个脚本会检查系统环境,生成Makefile文件。
在执行configure脚本时,可以指定一些选项,例如指定安装目录、指定编译器等。
例如,我们可以执行以下命令:./configure --prefix=/usr/local/libcurl --with-ssl这个命令指定了安装目录为/usr/local/libcurl,同时启用了SSL支持。
执行configure脚本后,会生成Makefile文件。
我们可以执行make命令来编译libcurl。
如果系统中有多个CPU核心,可以使用make -jN命令来加速编译,其中N为CPU核心数。
例如,我们可以执行以下命令:make -j4这个命令会使用4个CPU核心来编译libcurl。
编译完成后,我们可以执行make install命令来安装libcurl。
如果之前指定了安装目录,那么libcurl会被安装到指定目录下。
例如,我们可以执行以下命令:make install这个命令会将libcurl安装到/usr/local/libcurl目录下。
至此,我们已经成功地从源码编译了libcurl。
通过源码编译,我们可以自定义编译选项,以满足特定的需求。
同时,源码编译也可以帮助我们更好地理解libcurl的工作原理。
Linux下libcurl的编译和交叉编译⼀、下载curl源码⼆、创建⽬标输出⽬录 我创建了两个,⼀个放版本、⼀个放arm版本。
# mkdir build_linux build_arm三. 解压⽂件 # tar -xvf curl-7.63.0.tar.xz四. 配置并编译Linux版本: (--prefix指定编译输出安装路径 --enable-static 指定编译静态库)# ./configure --prefix=/home/gec/csdn/curl/build_linux --enable-static# make# make installARM版本:(--prefix指定编译输出安装路径 --enable-static 指定编译静态库 CC指定交叉编译⼯具链)# ./configure --host=arm-linux CC=arm-linux-gcc --prefix=/home/gec/csdn/curl/build_arm --enable-static# make# make install1.此处的 --enable-static 加上没效果,最后还是动态链接。
⾄少这个版本是这样的2.--prefix后⾯⼀定要是绝对路径,不能是相对路径五.移植到arm平台上,因为上⾯的 --enable-static 选项没起作⽤,需要将⽤到的库复制到对应路径,这⾥变态的不是从默认的/lib⽬录下读取库⽂件1.先到libcurl/bin下 readelf -d curl 查看curl的所需的库⽂件及库⽬录我这⾥显⽰库的路径是:“Library rpath: [/home/arm/share/4.开源库/curl-7.63.0/xxx/lib]”2. 在开发板上要创建同样的路径名字,并将库⽂件全部复制 mkdir /home/arm/share/4.开源库/curl-7.63.0/xxx/lib -p cp /nfs/4.开源库/curl-7.63.0/xxx/lib/ /home/arm/share/4.开源库/curl-7.63.0/xxx/lib/ 如果不做上述操作,执⾏curl命令时,不管后⾯是什么,⼀律返回:curl: (48) Error,也不提⽰是不是缺少库所造成的! 六. 复制bin下⾯的curl到开发板上,路径随意参考 不需要openssl需要openssl。
Libcurl实现断点续传⼀、LIbcurl简单介绍其实关于Liccurl的介绍最好的是看官⽅⽂档:⼏乎⼤部分的信息⾥⾯都能够查找到。
在这边简要介绍:1)跨平台特性,⼏乎所有平台都可以使⽤2)有许多其他语⾔的包装,如PHP、PYTHON等,也就是很多语⾔都可以使⽤libcurl3)Libcurl的所有接⼝被设计成线程安全(线程安全的意思是:在多线程之中可以同时调⽤⼀个API⽽不会互相影响,也就是函数可重⼊),另外要特别注意的是,任何⼀个libcurl的handle都不应该在多个线程之间共享,另外若使⽤HTTPS、FTPS需要OpenSSL或GnuTls 的⽀持。
4)⽀持IPV6,前提是在编译的时候打开相应的选项5)Libcurl性能很不错,但是若通过其他语⾔(⾮C语⾔)性能会有⼀定减弱,这和其他语⾔本⾝有关系6)Libcurl提供三种handle:easy_handle、multi_handle、share_handle easy_handle:为libcurl的最基础部分,所有的操作都是在easy_handle上进⾏的,⽐如发送、请求数据都是在其上进⾏的。
如果直接在easy_handle执⾏操作 curl_easy_perform 函数是阻塞的(即需要等到完成才返回) multi_handle:libcurl为异步操作提供的接⼝,允许调⽤⽅在⼀个线程中处理多个操作(就是easy_handle上的操作,注意是单线程下的),内部multi_handle采⽤堆栈的⽅式保存多个easy_handle,然后在⼀个线程中可以同时对多个easy_handle进⾏处理,multi_handle 的执⾏操作 curl_multi_perform 函数是⽴即返回的,不会阻塞 share_handle:有时候多个easy_handle需要分享⼀些信息,⽐如cookie,当⼀个连接获取⼀个新的cookie,就可以将这个cookie 共享到所有的连接上⼆、⼀些应⽤实例1、实现cookie共享 1)场景:客户端与服务器之间为了提⾼传输性能,建⽴了多个http连接。
libCurlopensslZlib的ARM移植libCurl/openssl/Zlib的ARM移植收藏本人使用环境Host linux(from ubuntu):jeos[just enougth OS]交叉编译器:/opt/timesys/toolchains/armv5l-linux/bin/armv5l-linux-gcc target Processor:ARM926EJ-S rev 5 (v5l)Hardware:Atmel AT91SAM9260-EK先开始libCurl 的移植过程:下载curl-7.20.0.tar.bz2解压至本目录,开始configure,由于之前一直发现配置不过,出现多次错误,这里直接给出正确的配置:cd curl-7.20.0 && ./configure--prefix=/win/530/curl/build --build=i686-linux--host=arm-linuxCC=/opt/timesys/toolchains/armv5l-linux/bin/armv5l-linux-gcc CFLAGS='-Os' --enable-debug --enable-optimize --enable-static--disable-ftp --without-zlib --disable-rtsp --disable-dict--disable-proxy --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smtp --disable-ipv6 --enable-http -enable-crypto-auth --without-gnutls --without-nss--without-ca-bundle --with-random=/dev/urandom export LDFLAGS="-static-L/opt/timesys/toolchains/armv5l-linux/lib" && configure碰到的错误:1.checking for "/dev/urandom"... configure: error: cannot check for file existence when cross compilinggoogle后发现答案:/forum/topic/137按照回答,由于是在主机上配置、编译,所以配置期间没找到适合于目标系统的随机数生成器,具体在/dev/urandom下面,但是我找了下,确实是有的:[root@openssl]# ls -al /dev/urandomcrw-rw-rw- 1 root root 1, 9 Jan 12 17:12 /dev/urandom[root@openssl]# file /dev/urandom/dev/urandom: character special引用回答的原文:#You may need to provide a parameter like'--with-random=/dev/urandom' to configure as it cannot detectthe presence of a random number generating device for a target system.2.checking for curl_socklen_t data type... unknown configure: error: cannot find data type for curl_socklen_t.在网上找了多次,没找到解决方法。
libcurl put post get 方法【实用版3篇】目录(篇1)1.介绍 libcurl 库2.libcurl 的 put、post、get 方法的定义和功能3.使用 libcurl 实现 put、post、get 方法的示例4.结论正文(篇1)一、介绍 libcurl 库libcurl 是一个用于传输数据的强大、易用、开源的 C 库。
它可以方便地处理各种网络数据传输任务,如 HTTP 请求、文件上传、FTP 文件传输等。
libcurl 支持多种协议,包括 HTTP, HTTPS, FTP, FTPS, SFTP, TFTP, LDAP, LDAPS, DICT, FILE, TELNET, RTSP, POP3, IMAP 等。
二、libcurl 的 put、post、get 方法的定义和功能1.put 方法put 方法是 HTTP 请求中的一种,用于向服务器上传文件或数据。
它将请求数据发送到服务器,然后等待服务器的响应。
2.post 方法post 方法是 HTTP 请求中的一种,用于向服务器提交数据。
它将请求数据发送到服务器,然后等待服务器的响应。
与 get 方法相比,post 方法通常用于传输较大的数据或需要保密的数据。
3.get 方法get 方法是 HTTP 请求中的一种,用于从服务器获取数据。
它向服务器发送请求,并接收服务器返回的数据作为响应。
目录(篇2)1.介绍 libcurl2.libcurl 的 put 方法3.libcurl 的 post 方法4.libcurl 的 get 方法5.结论正文(篇2)1.介绍 libcurllibcurl 是一个用于传输数据的强大且易用的库。
它可以用于多种协议,包括 HTTP, HTTPS, FTP, FTPS, SFTP, TFTP, LDAP, LDAPS, DICT, FILE, TELNET, RTSP, POP3, IMAP 等。
Linux下编译LibCURL编译环境操作系统: Red Hat Enterprise Linux Server release 5.4 64-bit编译⼯具: gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-46)1. 下载libssh2库地址:将libssh2-1.4.2.tar.gz上传⾄/home⽬录下2. 编译安装libssh2库$ cd /home$ tar -zxvf libssh2-1.4.2.tar.gz$ cd libssh2-1.4.2$ ./configure --with-libssl-prefix=/usr/local/openssl$ make && make install && make clean注:如果出现:configure: error: cannot find OpenSSL or Libgcrypt 错误修改为:./configure --with-libssl-prefix=/usr/local/openssl CPPFLAGS="-I/usr/local/openssl/include" LDFLAGS="-L/usr/local/openssl/lib"3. 下载LibCURL地址:http://curl.haxx.se/download.html以curl-7.27.0.tar.gz包为例,将curl-7.27.0.tar.gz上传⾄/home⽬录下4. 解压LibCURL$ cd /home$ tar -zxvf curl-7.27.0.tar.gz$ cd curl-7.27.05. 编译并安装编译$ ./configure --with-ssl=/usr/local/openssl --with-libssh2=/usr/local --with-zlib$ make && make install清理编译时的中间⽂件$ make clean6. 使⽤在/usr/local/lib中存放的⽣成的LibCURL库libcurl.a,可以直接⽤来参与静态编译。
libcurl curlopt_writefunction 对象方法摘要:1.libcurl简介2.curlopt_writefunction的作用3.对象方法的实现4.应用场景和示例5.注意事项正文:libcurl是一个流行的C库,用于实现多种协议的HTTP请求。
它提供了丰富的选项,以满足各种网络请求的需求。
在libcurl中,curlopt_writefunction是一个重要的回调函数,用于处理HTTP响应的数据输出。
本文将详细介绍curlopt_writefunction的使用方法和应用场景。
一、libcurl简介libcurl是一个免费、开源的C库,支持多种网络协议(如HTTP, HTTPS, FTP, FTPS, SFTP, TFTP等)。
它广泛应用于各种操作系统和平台,便于开发者轻松实现网络请求。
libcurl提供了丰富的选项,允许用户自定义请求和响应的处理方式。
二、curlopt_writefunction的作用curlopt_writefunction是一个回调函数,当libcurl接收到HTTP响应数据时,会调用此函数进行处理。
该函数接收两个参数:一个是输出缓冲区,用于存储响应数据;另一个是用户数据,可以自定义。
通过设置这个选项,用户可以自定义HTTP响应数据的处理方式,例如将响应数据写入文件或输出到控制台。
三、对象方法的实现在libcurl中,可以使用以下步骤设置curlopt_writefunction:1.初始化CURL环境:使用curl_global_init()函数进行全局初始化。
2.创建CURL句柄:使用curl_easy_init()函数创建一个CURL句柄。
3.设置curlopt_writefunction:使用curl_easy_setopt()函数设置回调函数。
4.执行网络请求:使用curl_easy_perform()函数发起请求。
5.清理资源:使用curl_easy_cleanup()函数释放句柄资源。
3.1获取html网页#include<stdio.h>#include<curl/curl.h>#include<stdlib.h>int main(int argc,char*argv[]){CURL*curl;//定义CURL类型的指针CURLcode res;//定义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 3.2网页下载保存实例//采用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_t write_data(void*ptr,size_t size,size_t nmemb,void*stream) {int written=fwrite(ptr,size,nmemb,(FILE*)fp);return written;}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 /tmp/baidu3.3进度条实例??显示文件下载进度//采用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) {return fwrite(ptr,size,nmemb,stream);}//这个函数是为了符合CURLOPT_READFUNCTION而构造的//数据上传时使用size_t my_read_func(void*ptr,size_t size,size_t nmemb,FILE*stream) {return fread(ptr,size,nmemb,stream);}//这个函数是为了符合CURLOPT_PROGRESSFUNCTION而构造的//显示文件传输进度,t代表文件大小,d代表传输已经完成部分int my_progress_func(GtkWidget*bar,double t,/*dltotal*/double d,/*dlnow*/double ultotal,double ulnow){/*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();return0;}void*my_thread(void*ptr){CURL*curl;CURLcode res;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);}return NULL;}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't create the thread");gdk_threads_enter();gtk_main();gdk_threads_leave();return0;}编译export PKG_CONFIG_PATH=/usr/lib/pkgconfig/gcc progress.c–o progress`pkg-config--libs–cflags gtk+-2..0`-lcurl–lgthread-2.0./progress /index.asp。
libcurl+openssl多平台编译curl-7.65.0 为例Linuxopenssl1)进⼊openssl源码根路径,如:/home/user/openssl-master,执⾏以下命令:./config; make -j82)此时会在源码根⽬录⽣成 libcrypto.a libcrypto.so libssl.a libssl.so 等相应的crypto及ssl的静态库与动态库libcurl1)进⼊libcur源码根路径,执⾏以下命令:2)依次执⾏以下命令mkdir build; cd buildmake ../ -DOPENSSL_ROOT_DIR=/home/user/openssl-master -DBUILD_SHARED_LIBS=true -DCURL_DISABLE_LDAP=true -DCURL_DISABLE_LDAPS=true -DCURL_ZLIB=falsemake -j83)此时会⽣成在 build/lib ⽬录会⽣成 libcurl.a 静态库⽂件将以下libcurl.a libssl.a libcrypto.a 或者相应.so拷贝到应⽤⼯程上链接Windowsopenssl1)进⼊openssl源码根路径,如:D:\openssl-master2)新建build.bat ⽂件,并保存以下内容:set CURPATH=%~dp0set TARGET="VC-WIN64A-masm"set VSCOMNTOOLS="C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build\vcvarsall.bat"set SHARED=call %VSCOMNTOOLS% x64mkdir buildcd buildperl ../Configure %TARGET% %SHARED% --prefix="%CURPATH%\build\prefix" --openssldir="%CURPATH%\build\install" --release perl configdata.pm --dumpnmake build_all_generatednmake PERL=no-perlnmake installcd ..脚本说明:如果编译32bit的,将TARGET修改为VC-WIN32,call %VSCOMNTOOLS% x64修改为 call %VSCOMNTOOLS% x86,如果编译debut版本,将--release修改为 --debug3)执⾏ build.bat ⽂件。
C++使用libcurl做HttpClient当使用C++做HTTP客户端时,目前通用的做法就是使用libcur l。
其官方网站的地址是/,该网站主要提供了Curl和libcurl。
Curl是命令行工具,用于完成FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE 以及LDAP的命令的请求及接收回馈。
libcurl提供给开发者,用于使用C++跨平台的开发各种网络协议的请求及响应。
里面的文档非常齐全,不过都是英文的。
本文提供最简单的demo使用libcurl开发HttpClient。
主要包括同步的HTTP GET、HTTP POST、HTTPS GET、HTTPS POST。
下载libcurl包,如果使用Linux平台,建议下载源文件编译;如果使用Windows平台,建议下载Win32 - MSVC,下载地址是:/do wnload.html1.#ifndef __HTTP_CURL_H__2.#define __HTTP_CURL_H__3.4.#include<string>5.6.class CHttpClient7.{8.public:9.CHttpClient(void);10.~CHttpClient(void);11.12.public:13./**14.* @brief HTTP POST请求15.* @param strUrl 输入参数,请求的Url地址,如:http://16.* @param strPost 输入参数,使用如下格式para1=val 1?2=val2&…17.* @param strResponse 输出参数,返回的内容18.* @return 返回是否Post成功19.*/20.int Post(const std::string& strUrl,const std::string & strPost, std::string& strResponse);21.22./**23.* @brief HTTP GET请求24.* @param strUrl 输入参数,请求的Url地址,如:http:// 25.* @param strResponse 输出参数,返回的内容26.* @return 返回是否Post成功27.*/28.int Get(const std::string& strUrl, std::string& strR esponse);29.30./**31.* @brief HTTPS POST请求,无证书版本32.* @param strUrl 输入参数,请求的Url地址,如:https:/ /33.* @param strPost 输入参数,使用如下格式para1=val 1?2=val2&…34.* @param strResponse 输出参数,返回的内容35.* @param pCaPath 输入参数,为CA证书的路径.如果输入为NULL,则不验证服务器端证书的有效性.36.* @return 返回是否Post成功37.*/38.int Posts(const std::string& strUrl,const std::strin g& strPost, std::string& strResponse,const char* pCaPath = N ULL);39.40./**41.* @brief HTTPS GET请求,无证书版本42.* @param strUrl 输入参数,请求的Url地址,如:https:/ /43.* @param strResponse 输出参数,返回的内容44.* @param pCaPath 输入参数,为CA证书的路径.如果输入为NULL,则不验证服务器端证书的有效性.45.* @return 返回是否Post成功46.*/47.int Gets(const std::string& strUrl, std::string& str Response,const char* pCaPath = NULL);48.49.public:50.void SetDebug(bool bDebug);51.52.private:53.bool m_bDebug;54.};55.56.#endif57.58.[cpp] view plaincopy59.#include"httpclient.h"60.#include"curl/curl.h"61.#include<string>62.63.CHttpClient::CHttpClient(void):64.m_bDebug(false)65.{66.67.}68.69.CHttpClient::~CHttpClient(void)70.{71.72.}73.74.static int OnDebug(CURL *, curl_infotype itype,ch ar* pData,size_t size,void*)75.{76.if(itype == CURLINFO_TEXT)77.{78.//printf("[TEXT]%s\n", pData);79.}80.else if(itype == CURLINFO_HEADER_IN)81.{82.printf("[HEADER_IN]%s\n", pData);83.}84.else if(itype == CURLINFO_HEADER_OUT)85.{86.printf("[HEADER_OUT]%s\n", pData);87.}88.else if(itype == CURLINFO_DATA_IN)89.{90.printf("[DATA_IN]%s\n", pData);91.}92.else if(itype == CURLINFO_DATA_OUT)93.{94.printf("[DATA_OUT]%s\n", pData);95.}96.return0;97.}98.99.static size_t OnWriteData(void* buffer,size_t size, size_t nmemb,void* lpVoid)100.{101.std::string* str =dynamic_cast<std::string*>((std:: string*)lpVoid);102.if( NULL == str || NULL == buffer )103.{104.return-1;105.}106.107.char* pData =(char*)buffer;108.str->append(pData, size * nmemb);109.return nmemb;110.}111.112.int CHttpClient::Post(const std::string& strUrl,con st std::string& strPost, std::string& strResponse)113.{114.CURLcode res;115.CURL* curl = curl_easy_init();116.if(NULL == curl)117.{118.return CURLE_FAILED_INIT;119.}120.if(m_bDebug)121.{122.curl_easy_setopt(curl, CURLOPT_VERBOSE,1);123.curl_easy_setopt(curl,CURLOPT_DEBUGFUNCTIO N,OnDebug);124.}125.curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());126.curl_easy_setopt(curl, CURLOPT_POST,1);127.curl_easy_setopt(curl,CURLOPT_POSTFIELDS,strP ost.c_str());128.curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);129.curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);130.curl_easy_setopt(curl,CURLOPT_WRITEDATA,(voi d*)&strResponse);131.curl_easy_setopt(curl, CURLOPT_NOSIGNAL,1);132.curl_easy_setopt(curl,CURLOPT_CONNECTTIMEO UT,3);133.curl_easy_setopt(curl, CURLOPT_TIMEOUT,3);134.res = curl_easy_perform(curl);135.curl_easy_cleanup(curl);136.return res;137.}138.139.int CHttpClient::Get(const std::string& strUrl, std:: string& strResponse)140.{141.CURLcode res;142.CURL* curl = curl_easy_init();143.if(NULL == curl)144.{145.return CURLE_FAILED_INIT;146.}147.if(m_bDebug)148.{149.curl_easy_setopt(curl, CURLOPT_VERBOSE,1);150.curl_easy_setopt(curl,CURLOPT_DEBUGFUNCTIO N,OnDebug);151.}152.<pre name="code"class="cpp"> curl_easy_seto pt(curl, CURLOPT_URL, strUrl.c_str());153.curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);154.curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);155.curl_easy_setopt(curl,CURLOPT_WRITEDATA,(voi d*)&strResponse);156./**157.* 当多个线程都使用超时处理的时候,同时主线程中有sleep或是wait等操作。
libcurl put post get 方法【实用版4篇】目录(篇1)1.引言2.libcurl 简介3.libcurl 的 PUT 方法4.libcurl 的 POST 方法5.libcurl 的 GET 方法6.结论正文(篇1)1.引言在网络编程中,HTTP 请求是常见的操作之一。
libcurl 是一个用于传输数据的强大库,支持多种网络协议。
它提供了 PUT、POST 和 GET 等方法来满足不同场景的需求。
本文将对这些方法进行详细介绍。
2.libcurl 简介libcurl 是一个用于传输数据的开源库,支持多种网络协议,如 HTTP, HTTPS, FTP, FTPS, SFTP, TFTP 等。
它提供了丰富的 API,方便开发者在不同的编程语言中实现网络请求。
libcurl 支持跨平台使用,可以在Windows、Linux、macOS 等操作系统上使用。
3.libcurl 的 PUT 方法libcurl 的 PUT 方法用于向指定的 URL 上传数据。
使用 PUT 方法时,需要先创建一个 HTTP 请求,然后使用 CURLOPT_PUT 接口设置请求方式为 PUT,接着使用 CURL_HTTP_请求函数发送请求。
在请求头中,需要设置"Content-Type"为"application/x-www-form-urlencoded"或"application/json"等,以便告知服务器上传数据的类型。
4.libcurl 的 POST 方法libcurl 的 POST 方法用于向指定的 URL 提交数据。
使用 POST 方法时,需要先创建一个 HTTP 请求,然后使用 CURLOPT_POST 接口设置请求方式为 POST,接着使用 CURL_HTTP_请求函数发送请求。
在请求头中,需要设置"Content-Type"为"application/x-www-form-urlencoded"或"application/json"等,以便告知服务器提交数据的类型。
C++⽤libcurl库进⾏http通讯⽹络编程⽬录索引:⼀、LibCurl基本编程框架⼆、⼀些基本的函数三、curl_easy_setopt函数部分选项介绍四、curl_easy_perform 函数说明(error 状态码)五、libcurl使⽤的HTTP消息头六、获取http应答头信息七、多线程问题⼋、什么时候libcurl⽆法正常⼯作九、关于密码⼗、HTTP验证⼗⼀、代码⽰例1.基本的http GET/POST操作2获取html⽹页3⽹页下载保存实例4进度条实例显⽰⽂件下载进度5断点续传实例⼀、LibCurl基本编程框架是⼀个跨平台的⽹络协议库,⽀持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。
libcurl同样⽀持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传, HTTP基本表单上传,代理,cookies,和⽤户认证。
想要知道更多关于libcurl的介绍,可以到官⽹上去了解,在这⾥不再详述。
win32版的libcurl下载地址:在基于LibCurl的程序⾥,主要采⽤callback function (回调函数)的形式完成传输任务,⽤户在启动传输前设置好各类参数和回调函数,当满⾜条件时libcurl将调⽤⽤户的回调函数实现特定功能。
下⾯是利⽤libcurl完成传输任务的流程:1. 调⽤curl_global_init()初始化libcurl2. 调⽤curl_easy_init()函数得到 easy interface型指针3. 调⽤curl_easy_setopt()设置传输选项4. 根据curl_easy_setopt()设置的传输选项,实现回调函数以完成⽤户特定任务5. 调⽤curl_easy_perform()函数完成传输任务6. 调⽤curl_easy_cleanup()释放内存在整过过程中设置curl_easy_setopt()参数是最关键的,⼏乎所有的libcurl程序都要使⽤它。
curl的基本使用及libcurlcurl的基本使用及libcurlcurllibcurl文件下载httppost1 curl 是一个强大的命令行工具,一般被称为下载工具;其实curl可以执行HTTP HTTPS FTP等协议的绝大部分请求,完成一般windows等系统上下载工具的绝大多数功能。
网址: [没错,来自瑞典]CURL 写道curl is a command line tool for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP. curl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, cookies, user+password authentication (Basic, Digest, NTLM, Negotiate, kerberos...), file transfer resume, proxy tunneling and a busload of other useful tricks.CURL 写道Curl is free and open software that compiles and runs under a wide variety of operating systems. Curl exists thanks to efforts from many contributors.The most recent stable version of curl is version 7.22.0, released on 13th of September 2011. Currently, 110 of the listed archives are of the latest version.2 CURL的基本使用网络写道1、获得一张页面使用命令:curl这是最简单的使用方法。
交叉编译是指在一个平台上生成另一个平台上的可执行文件。
对于libcurl,如果你想在非Linux 平台上交叉编译它,你需要遵循特定的步骤。
以下是一个简化的指南,说明如何在非Linux 系统上交叉编译libcurl:
安装交叉编译工具链:
根据你的目标平台,你可能需要安装一个交叉编译工具链。
例如,如果你想为ARM 架构编译,你可能需要安装像arm-linux-gnueabihf-gcc这样的交叉编译器。
配置交叉编译选项:
使用configure脚本为交叉编译设置正确的选项。
验证:
为了确保你已成功交叉编译,你可以尝试在目标系统上运行一些简单的测试。
注意事项:
确保你的交叉编译工具链是最新的,并且与你的目标平台兼容。
在某些情况下,你可能需要手动设置库路径或链接器路径。
根据你的具体需求和目标平台,你可能还需要考虑其他配置选项。
查找特定于平台的文档:
不同的平台和工具链可能有其特定的交叉编译要求和步骤。
因此,查找特定于你目标平台的libcurl交叉编译文档可能会很有帮助。
最后,如果你在交叉编译过程中遇到任何问题,可以查阅libcurl的官方文档、邮件列表或论坛,那里可能有其他开发者遇到并解决了相同的问题。
libcurl head方法(一)libcurl head详解什么是libcurl headlibcurl是一个强大而灵活的开源网络传输库,提供了广泛的协议支持。
而libcurl head则是libcurl库中关于请求头的相关功能。
为什么需要设置请求头在进行网络请求时,有时候我们需要在请求中设置一些自定义的头信息,例如User-Agent、Authorization等。
这些自定义的头信息可以帮助我们实现更精细的控制和定制。
设置请求头的方法方法一:使用curl_easy_setopt函数libcurl库提供了curl_easy_setopt函数,通过传入不同的设置选项,可以设置各种请求头。
CURL *curl = curl_easy_init(); // 初始化curl句柄curl_easy_setopt(curl, CURLOPT_URL, " // 设置请求的URL curl_easy_setopt(curl, CURLOPT_HTTPHEADER, "Content-Type: application/json"); // 设置Content-Type头信息...方法二:使用curl_easy_setopt函数的CURLOPT_HEADER选项另一种设置请求头的方法是使用curl_easy_setopt函数的CURLOPT_HEADER选项。
该选项用于启用或禁用收集响应头。
CURL *curl = curl_easy_init(); // 初始化curl句柄curl_easy_setopt(curl, CURLOPT_URL, " // 设置请求的URL curl_easy_setopt(curl, CURLOPT_HEADER, 1); // 启用收集响应头...方法三:使用curl_slist_append函数利用curl_slist_append函数,可以逐个设置请求头。
libcurl简单⽤法1.全局初始化API应⽤程序在使⽤libcurl之前,必须先初始化libcurl。
libcurl只需初始化⼀次。
可以使⽤以下语句进⾏初始化: CURLcode curl_global_init(int flags); ⼀般flags使⽤CURL_GLOBAL_ALL当应⽤程序不再使⽤libcurl的时候,应该调⽤curl_global_cleanup[声明:void curl_global_cleanup(void)]释放相关的资源。
在程序中,应当避免多次调⽤curl_global_init和curl_global_cleanup。
它们只能被调⽤⼀次。
返回值0成功,⾮0值代表错误。
若错误,所有api不得调⽤。
#define CURL_GLOBAL_SSL (1<<0)//设定⽀持SSL#define CURL_GLOBAL_WIN32 (1<<1)//libcurl初始化winsock库#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32)#define CURL_GLOBAL_NOTHING 0#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL#define CURL_GLOBAL_ACK_EINTR (1<<2)//CURL_GLOBAL_ACK_EINTR 在7.69.0以后将没有任何作⽤。
在在7.69.0之前:当设置此标志时,curl将在连接或等待数据时确认EINTR条件。
否则,curl将 2.curl其他常⽤API2.1.easy interface 最基本的原则是绝对不要同时在多个线程之间共享⼀个libcurl的句柄。
确保任何时候⼀个句柄只是在⼀个线程⾥使⽤。
你可以在多个线程之间传递句柄,但是你不能使⽤。
libcurl是线程安全的,除了以下两种情况:信号量和SSL/TLS句柄。
vs2008构建和使用libcurl静态库学步园1>下载CURL源代码curl-7.26.0.zip2>用VC2008/2005打开工程curl-7.26.0\lib\libcurl.vcproj,转换下工程并构建,可以直接编译成功!3>新建个控制台工程测试下刚才编译的静态库libcurl.lib,可以在libcurl\curl-7.26.0\docs\examples目录找个简单的使用curl的例子,在这个工程选项Configuration Properties-| C/C++ -|General -|Additional Include Directories 路径中加入curl7.26\include, 在linker选项卡,指定静态库路径和静态库的名字libcurl.lib,代码如下[cpp] viewplaincopy1.#include "stdafx.h"2.#include <Windows.h>3.#include "curl/curl.h"4.5.int _tmain(int argc, _TCHAR* argv[])6.{7.CURL *curl;8.CURLcode res;9.10.curl = curl_easy_init();11.if(curl) {12.curl_easy_setopt(curl, CURLOPT_URL, " /?kduba");13.res = curl_easy_perform(curl);14.curl_easy_cleanup(curl);15.}16.return 0;17.}此时cpp文件可以编译,但是链接报错1>testcurl.obj : error LNK2001: unresolved external symbol __imp__curl_easy_init1>testcurl.obj : error LNK2001: unresolved external symbol __imp__curl_easy_setopt1>testcurl.obj : error LNK2001: unresolved external symbol __imp__curl_easy_perform1>testcurl.obj : error LNK2001: unresolved external symbol __imp__curl_easy_cleanup看样子根本没有链接静态库,虽然刚才指定了库的路径,确认库路径的名字没错,于是看了下curl_easy_init 这个函数的定义,[cpp] viewplaincopy1.CURL_EXTERN CURL *curl_easy_init(void);2.CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CU RLoption option, ...);3.CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);4.CURL_EXTERN void curl_easy_cleanup(CURL *curl);5.6.7./*8.* Decorate exportable functions for Win32 and Symbian OS DLL linking.9.* This avoids using a .def file for building libcurl.dll.10.*/11.#if (defined(WIN32) || defined(_WIN32) || defined(__SY MBIAN32__)) && \12.!defined(CURL_STATICLIB)13.#if defined(BUILDING_LIBCURL)14.#define CURL_EXTERN __declspec(dllexport)15.#else16.#define CURL_EXTERN __declspec(dllimport)17.#endif18.#else看到这里于是明白了,如下操作:在libcurl静态库工程选项Configuration Properties-| C/C++ -| Preprocessor 中加上BUILDING_LIBCURL宏在测试工程选项Configuration Properties-| C/C++ -| Preprocessor 中加上CURL_STATICLIB宏,然后依次重新构建两个工程发现测试工程链接不过1>libcurl_MT.lib(easy.obj) : error LNK2001: unresolved external symbol __imp__WSACleanup@01>libcurl_MT.lib(telnet.obj) : error LNK2001: unresolved external symbol __imp__WSACleanup@01>libcurl_MT.lib(easy.obj) : error LNK2001: unresolved external symbol __imp__WSAStartup@81>libcurl_MT.lib(telnet.obj) : error LNK2001: unresolved external symbol __imp__WSAStartup@81>libcurl_MT.lib(tftp.obj) : error LNK2001: unresolved external symbol __imp__WSAGetLastError@01>libcurl_MT.lib(telnet.obj) : error LNK2001: unresolved external symbol __imp__WSAGetLastError@01>libcurl_MT.lib(ftp.obj) : error LNK2001: unresolved external symbol__imp__WSAGetLastError@01>libcurl_MT.lib(select.obj) : error LNK2001: unresolved external symbol __imp__WSAGetLastError@01>libcurl_MT.lib(asyn-thread.obj) : error LNK2001:1>libcurl_MT.lib(transfer.obj) : error LNK2001: unresolved external symbol __imp__WSAGetLastError@01>libcurl_MT.lib(sendf.obj) : error LNK2001: unresolved external symbol __imp__WSAGetLastError@01>libcurl_MT.lib(connect.obj) : error LNK2001: unresolved external symbol __imp__WSAGetLastError@01>libcurl_MT.lib(sendf.obj) : error LNK2001: unresolved external symbol __imp__send@161>libcurl_MT.lib(telnet.obj) : error LNK2001: unresolved external symbol __imp__send@161>libcurl_MT.lib(sendf.obj) : error LNK2001: unresolved external symbol __imp__recv@161>libcurl_MT.lib(connect.obj) : error LNK2001: unresolved external symbol __imp__recv@161>libcurl_MT.lib(connect.obj) : error LNK2001: unresolved external symbol __imp__getsockname@121>libcurl_MT.lib(ftp.obj) : error LNK2001: unresolved external symbol__imp__getsockname@121>libcurl_MT.lib(connect.obj) : error LNK2001: unresolved external symbol __imp__getpeername@121>libcurl_MT.lib(connect.obj) : error LNK2001: unresolved external symbol __imp__ntohs@41>libcurl_MT.lib(telnet.obj) : error LNK2001: unresolved external symbol __imp__ntohs@41>libcurl_MT.lib(ftp.obj) : error LNK2001: unresolved external symbol__imp__ntohs@41>libcurl_MT.lib(connect.obj) : error LNK2001: unresolved external symbol __imp__WSASetLastError@41>libcurl_MT.lib(curl_addrinfo.obj) : error LNK2001:1>libcurl_MT.lib(select.obj) : error LNK2001: unresolved external symbol __imp__WSASetLastError@41>libcurl_MT.lib(connect.obj) : error LNK2001: unresolved external symbol __imp__getsockopt@201>libcurl_MT.lib(connect.obj) : error LNK2001: unresolved external symbol __imp__setsockopt@201>libcurl_MT.lib(connect.obj) : error LNK2001: unresolved external symbol __imp__connect@121>libcurl_MT.lib(connect.obj) : error LNK2001: unresolved external symbol __imp__bind@121>libcurl_MT.lib(tftp.obj) : error LNK2001: unresolved external symbol __imp__bind@121>libcurl_MT.lib(ftp.obj) : error LNK2001: unresolved external symbol__imp__bind@121>libcurl_MT.lib(connect.obj) : error LNK2001: unresolved external symbol __imp__htons@41>libcurl_MT.lib(curl_addrinfo.obj) : error LNK2001: unresolved external symbol __imp__htons@41>libcurl_MT.lib(telnet.obj) : error LNK2001: unresolved external symbol __imp__htons@41>libcurl_MT.lib(ftp.obj) : error LNK2001: unresolved external symbol__imp__htons@41>libcurl_MT.lib(connect.obj) : error LNK2001: unresolved external symbol __imp__closesocket@41>libcurl_MT.lib(connect.obj) : error LNK2001: unresolved external symbol __imp__socket@121>libcurl_MT.lib(curl_addrinfo.obj) : error LNK2001: unresolved external symbol __imp__freeaddrinfo@41>libcurl_MT.lib(curl_addrinfo.obj) : error LNK2001:unresolved external symbol __imp__getaddrinfo@161>libcurl_MT.lib(tftp.obj) : error LNK2001: unresolved external symbol __imp__sendto@241>libcurl_MT.lib(tftp.obj) : error LNK2001: unresolved external symbol __imp__recvfrom@241>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_unbind_s1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_msgfree1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ber_free1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_memfree1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_value_free_len1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_get_values_len1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_next_attribute1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_first_attribute1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_get_dn1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_next_entry1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_first_entry1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_search_s1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolvedexternal symbol __imp__ldap_simple_bind_s1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_init1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_set_option1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_err2string1>libcurl_MT.lib(ftp.obj) : error LNK2001: unresolved external symbol__imp__listen@81>libcurl_MT.lib(ftp.obj) : error LNK2001: unresolved external symbol__imp__accept@121>libcurl_MT.lib(select.obj) : error LNK2001: unresolved external symbol ___WSAFDIsSet@81>libcurl_MT.lib(select.obj) : error LNK2001: unresolved external symbol __imp__select@201>libcurl_MT.lib(nonblock.obj) : error LNK2001: unresolved external symbol __imp__ioctlsocket@121>libcurl_MT.lib(curl_gethostname.obj) : error LNK2001: unresolved external symbol__imp__gethostname@8谷歌了下, WSACleanup function msdn 是需要链接Ws2_32.lib, 同样的道理1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_unbind_s1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_msgfree1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ber_free1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_memfree1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolvedexternal symbol __imp__ldap_value_free_len1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_get_values_len1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_next_attribute1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_first_attribute1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_get_dn1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_next_entry1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_first_entry1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_search_s1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_simple_bind_s1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_init1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_set_option1>libcurl_MT.lib(ldap.obj) : error LNK2001: unresolved external symbol __imp__ldap_err2string是少了Wldap32.lib在libcurl静态库工程选项Configuration Properties-|Librarian -| Additional Dependencies 中加上依赖项Ws2_32.lib Wldap32.lib 再依次重编两个工程,就OK了编译选项设为/MD时候,不需要添加Ws2_32.lib Wldap32.lib小结:1>对于开源代码的编译问题,还是要从代码入手,包括注释2>静态库构建的时候很容易,但是要知道是不是成功的,还得编个测试工程才能知道是不是真的OK。
libcurl教程 译者注:这是一篇介绍如何使用libcurl的入门教程。文档不是逐字逐句按原文翻译,而是根据笔者对libcurl的理解,参考原文写成。文中用到的一 些例子,可能不是出自原文,而是笔者在学习过程中,写的一些示例程序(笔者使用的libcurl版本是:7.19.6)。出现在这里主要是为了更好的说明 libcurl的某些api函数的使用。许多例子都参考libcurl提供的example代码。原文example中的提供的示例程序完全使用C语言, 而这里笔者提供的例子使用C++语言。因为能力有限,对于libcurl的某些理解和使用可能有误,欢迎批评指正。
目 标 本文档介绍了在应用程序开发过程中,如何正确使用libcurl的基本方式和指导原则。文档使用C语言来调用libcurl的接口,当然也适用于其他与C 语言接近的语言。 文档主要针对使用libcurl来进行开发的人员。文档所掼的应用程序泛指你写的源代码,这些代码使用了libcurl进行数据传输。 更多关于libcurl的功能和接口信息,可以在相关的主页上查阅。 编译源码 有很多种不同的方式来编译C语言代码。这里使用UNIX平台下的编译方式。即使你使用的是其他的操作系统,你仍然可以通过阅读本文档来获取许多有用的信 息。 编译 你的编译器必须知道libcurl头文件的位置。所以在编译的时候,你要设置头文件的包含路径。可以使用curl-config工具来获取这方面的信息: $ curl-config –cflags 链接 编译完源码(这时的源代码不是指libcurl的源代码,你是你自己写的程序代码)之后,你还必须把目标文件链接成单个可执行文件。你要链接 libcurl库,以及libcurl所依赖的其他库,例如OpenSLL库。当然可能还需要一些其他的操作系统库。最后你还要设置一些编译选项,当然可 以使用curl-config工具简化操作:
$curl-config –libs 是否使用SSL 定制编译libcurl。与其他库不同的是,libcurl可以定制编译,根据实际需要是否支持某些特性,如是否支持SSL传输,像HTTPS和 FTPS。如果决定需要支持SSL,必须在编译时正确的设置。可以使用‟curl-config‟来判断libcurl库是否支持SSL:
$ curl-config –feature autoconf宏 当你编写配置脚本来检测libcurl及其相应设置时,你可以使用预定义宏。文档docs/libcurl/libcurl.m4告诉你如何使用这些宏。 跨平台的可移植的代码 libcurl的开发人员花费很大的努力,使libcurl尽可能在大多数平台上正常运行。 全局初始化 应用程序在使用libcurl之前,必须先初始化libcurl。libcurl只需初始化一次。可以使用以下语句进行初始化: curl_global_init(); curl_global_init()接收一个参数,告诉libcurl如何初始化。参数CURL_GLOBAL_ALL 会使libcurl初始化所有的子模块和一些默认的选项,通常这是一个比较好的默认参数值。还有两个可选值:
CURL_GLOBAL_WIN32 只能应用于Windows平台。它告诉libcurl初始化winsock库。如果winsock库没有正确地初始化,应用程序就不能使用socket。 在应用程序中,只要初始化一次即可。 CURL_GLOBAL_SSL 如果libcurl在编译时被设定支持SSL,那么该参数用于初始化相应的SSL库。同样,在应用程序中,只要初始化一次即可。 libcurl有默认的保护机制,如果在调用curl_easy_perform时它检测到还没有通过curl_global_init进行初始 化,libcurl会根据当前的运行时环境,自动调用全局初始化函数。但必须清楚的是,让系统自已初始化不是一个好的选择。
当应用程序不再使用libcurl的时候,应该调用curl_global_cleanup来释放相关的资源。 在程序中,应当避免多次调用curl_global_init和curl_global_cleanup。它们只能被调用一次。 libcurl提供的功能
在运行时根据libcurl支持的特性来进行开发,通常比编译时更好。可以通过调用curl_version_info函数返回的结构体来获取运行时的具 体信息,从而确定当前环境下libcurl支持的一些特性。下面是笔者在visual studio2008中调用相关函数获取libcurl版本信息的截图:
使用easy interface
首先介绍libcurl中被称为easy interface的api函数,所有这些函数都是有相同的前缀:curl_easy 。 当前版本的libcurl也提供了multi interface,关于这些接口的详细使用,在下面的章节中会有介绍。在使用multi interface之前,你首先应该理解如何使用easy interface。 要使用easy interface,首先必须创建一个easy handle,easy handle用于执行每次操作。基本上,每个线程都应该有自己的easy handle用于数据通信(如果需要的话)。千万不要在多线程之间共享同一个easy handle。下面的函数用于获取一个easy handle :
CURL *easy_handle = curl_easy_init(); 在easy handle上可以设置属性和操作(action)。easy handle就像一个逻辑连接,用于接下来要进行的数据传输。 使用curl_easy_setopt函数可以设置easy handle的属性和操作,这些属性和操作控制libcurl如何与远程主机进行数据通信。一旦在easy handle中设置了相应的属性和操作,它们将一直作用该easy handle。也就是说,重复使用easy hanle向远程主机发出请求,先前设置的属性仍然生效。 easy handle的许多属性使用字符串(以\0结尾的字节数组)来设置。通过curl_easy_setopt函数设置字符串属性时,libcurl内部会自 动拷贝这些字符串,所以在设置完相关属性之后,字符串可以直接被释放掉(如果需要的话)。
easy handle最基本、最常用的属性是URL。你应当通过CURLOPT_URL属性提供适当的URL: curl_easy_setopt(easy_handle, CURLOPT_URL, "http://blog.csdn.net/JGood "); 假设你要获取URL所表示的远程主机上的资源。你需要写一段程序用来完成数据传输,你可能希望直接保存接收到的数据而不是简单的在输出窗口中打印它们。所 以,你必须首先写一个回调函数用来保存接收到的数据。回调函数的原型如下:
size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp); 可以使用下面的语句来注册回调函数,回调函数将会在接收到数据的时候被调用: curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, write_data); 可以给回调函数提供一个自定义参数,libcurl不处理该参数,只是简单的传递: curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, &internal_struct); 如果你没有通过CURLOPT_WRITEFUNCTION属性给easy handle设置回调函数,libcurl会提供一个默认的回调函数,它只是简单的将接收到的数据打印到标准输出。你也可以通过 CURLOPT_WRITEDATA属性给默认回调函数传递一个已经打开的文件指针,用于将数据输出到文件里。
下面是一些平台相关的注意点。在一些平台上,libcurl不能直接操作由应用程序打开的文件。所以,如果使用默认的回调函数,同时通过 CURLOPT_WRITEDATA属性给easy handle传递一个文件指针,应用程序可能会执行失败。如果你希望自己的程序能跑在任何系统上,你必须避免出现这种情况。
如果以win32动态连接库的形式来使用libcurl,在设置CURLOPT_WRITEDATA属性时,你必须同时 使用CURLOPT_WRITEFUNCTION来注册回调函数。否则程序会执行失败(笔者尝试只传递一个打开的文件指针而不显式设置回调函数,程序并没 有崩溃。可能是我使用的方式不正确。)。
当然,libcurl还支持许多其他的属性,在接下来的篇幅里,你将会逐步地接触到它们。调用下面的函数,将执行真正的数据通信: success = curl_easy_perform(easy_handle); curl_easy_perfrom将连接到远程主机,执行必要的命令,并接收数据。当接收到数据时,先前设置的回调函数将被调用。libcurl可能一 次只接收到1字节的数据,也可能接收到好几K的数据,libcurl会尽可能多、及时的将数据传递给回调函数。回调函数返回接收的数据长度。如果回调函数 返回的数据长度与传递给它的长度不一致(即返回长度 != size * nmemb),libcurl将会终止操作,并返回一个错误代码。
当数据传递结束的时候,curl_easy_perform将返回一个代码表示操作成功或失败。如果需要获取更多有关通信细节的信息,你可以设置 CURLOPT_ERRORBUFFER属性,让libcurl缓存许多可读的错误信息。
easy handle在完成一次数据通信之后可以被重用。这里非常建议你重用一个已经存在的easy handle。如果在完成数据传输之后,你创建另一个easy handle来执行其他的数据通信,libcurl在内部会尝试着重用上一次创建的连接。
对于有些协议,下载文件可能包括许多复杂的子过程:日志记录、设置传输模式、选择当前文件夹,最后下载文件数据。使用libcurl,你不需要关心这一 切,你只需简单地提供一个URL,libcurl会给你做剩余所有的工作。