Linux C libcurl安装及使用

一、libcurl简介及安装

libcurl是一个跨平台的网络协议库,支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传, HTTP基本表单上传,代理,cookies和用户认证。

libcurl的官网:http://curl.haxx.se/
库下载:https://github.com/curl/curl/releases/tag/curl-7_71_1

1.1 下载curl-7.71.1.tar.gz
Linux C libcurl安装及使用_第1张图片

1.2 安装步骤:
(1)解压curl-7.71.1.tar.gz压缩包

tar xvf curl-7.71.1.tar.gz

(2)浏览下curl-7.71.1/docs/INSTALL.md,有libcurl在unix环境下的安装步骤

A normal Unix installation is made in three or four steps (after you’ve unpacked the source archive):

./configure
make
make test (optional)
make install

You probably need to be root when doing the last command.

Get a full listing of all available configure options by invoking it
like:

./configure --help

If you want to install curl in a different file hierarchy than/usr/local, specify that when running configure:
./configure --prefix=/path/to/curl/tree

1、./configure --prefix=$PWD/_install 配置安装路径为当前路径下_install文件夹
2、make 编译
3、make install 编译后的文件拷贝到指定文件夹,此时才会出现_install文件夹

二、libcurl的函数使用

1、curl_global_init函数
初始化libcurl

头文件
#include
函数原型
CURLcode curl_global_init(long flags);
参数
flags
CURL_GLOBAL_ALL //初始化所有的可能的调用
CURL_GLOBAL_SSL //初始化支持 安全套接字层
CURL_GLOBAL_NOTHING //没有额外的初始化
返回
成功返回0,失败则返回非0。

如果这个函数在curl_easy_init函数调用时还没调用,它讲由libcurl库自动调用,所以多线程下最好主动调用该函数以防止在线程中curl_easy_init时多次调用。
注意:虽然libcurl是线程安全的,但curl_global_init是不能保证线程安全的,所以不要在每个线程中都调用curl_global_init,应该将该函数的调用放在主线程中。

2、curl_global_cleanup函数
结束libcurl使用的时候,用来对curl_global_init做的工作清理。类似于close的函数

头文件
#include
函数原型
void curl_global_cleanup(void);

注意:虽然libcurl是线程安全的,但curl_global_cleanup是不能保证线程安全的,所以不要在每个线程中都调用curl_global_init,应该将该函数的调用放在主线程中。

3、curl_easy_init函数
初始化一个CURL的指针(类似于返回FILE类型的指针一样)

头文件
#include
函数原型 CURL curl_easy_init( );
返回
CURL
对象, 一般都用在easy系列的函数中

4、curl_easy_cleanup函数
这个调用用来结束一个会话,与curl_easy_init配合着用

头文件
#include
函数原型
void curl_easy_cleanup(CURL *handle);
参数
CURL类型的指针

5、curl_easy_setopt函数
设置各种curl参数,告诉curl库,程序将有如何的行为

头文件
#include
函数原型
CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);
参数
handle:CURL类型的指针
option:CURLoption类型的选项
parameter:既可以是个函数的指针,也可以是某个对象的指针,也可以是个long型的变量。
它用什么这取决于第二个参数option。
返回
成功返回0,失败则返回非0。

parameter部分常见选项:

(1)CURLOPT_URL
设置访问URL
(2)CURLOPT_HTTPHEADER
设置请求头
(3)CURLOPT_WRITEFUNCTION,CURLOPT_WRITEDATA
回调函数原型为:size_t function( void *ptr, size_t size, size_t nmemb, void *stream); 函数将在libcurl接收到数据后被调用,因此函数多做数据保存的功能,如处理下载文件。CURLOPT_WRITEDATA 用于表明CURLOPT_WRITEFUNCTION函数中的stream指针的来源。
如果你没有通过CURLOPT_WRITEFUNCTION属性给easy handle设置回调函数,libcurl会提供一个默认的回调函数,它只是简单的将接收到的数据打印到标准输出。你也可以通过 CURLOPT_WRITEDATA属性给默认回调函数传递一个已经打开的文件指针,用于将数据输出到文件里。
(4)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指针的来源。
(5)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指针来源。
(6)CURLOPT_TIMEOUT,CURLOPT_CONNECTIONTIMEOUT
CURLOPT_TIMEOUT 由于设置传输时间,CURLOPT_CONNECTIONTIMEOUT 设置连接等待时间

6、curl_easy_perform函数
执行curl的各种操作的,并且通过分析其返回值,可以判断curl执行的情况

头文件
#include
函数原型
CURLcode curl_easy_perform(CURL *handle);
参数
handle:CURL类型的指针
返回
成功返回0,失败则返回错误码对应的值。

主要错误码及对应值说明:
(1)CURLE_OK—0
任务完成一切都好
(2)CURLE_UNSUPPORTED_PROTOCOL—1
不支持的协议,由URL的头部指定
(3)CURLE_COULDNT_CONNECT—7
不能连接到remote 主机或者代理
(4)CURLE_REMOTE_ACCESS_DENIED—9
访问被拒绝
(5)CURLE_HTTP_RETURNED_ERROR—22
Http返回错误
(6)CURLE_READ_ERROR—26
读本地文件错误

7、curl_slist_append函数
添加请求头信息

头文件
#include
函数原型
struct curl_slist *curl_slist_append(struct curl_slist *headers, const char * string);
参数
headers:结构体curl_slist指针,用于存储请求头信息,类似于链表。
string:要添加的请求头信息,包括属性名和属性值,字符串格式:attr:value
返回
新的结构体curl_slist指针。

8、curl_slist_free_all函数

释放请求头资源,避免导致内存泄漏
头文件
#include
函数原型
void curl_slist_free_all(struct curl_slist *headers);
参数
headers:结构体curl_slist指针

三、例程

//文件mycurl.c
#include 
#include 
#include 
#include 

#define true 1
#define false 0
typedef unsigned int bool;

size_t HandHandler( void *ptr, size_t size, size_t nmemb, void *stream)
{
     
	int buf_size=size*nmemb;
    char *buf=malloc(buf_size+1);
    strncpy(buf,ptr,buf_size+1);
    printf("%s\n",buf);
    free(buf);
    return buf_size;
}
size_t ReadHandler( void *ptr, size_t size, size_t nmemb, void *stream)
{
     
	int buf_size=size*nmemb;
	char *buf=malloc(buf_size+1);
	strncpy(buf,ptr,buf_size+1);
	//printf("===========get data size:%d bytes===========\n",buf_size);
	//printf("%s\n",buf);
	fwrite(buf,size,nmemb,stream);
	free(buf);
	return buf_size;
}

bool getUrl(char *filename)
{
     
    CURL *curl;
    CURLcode res;
    FILE *fp;
    if ((fp = fopen(filename, "w")) == NULL)  // 返回结果用文件存储
        return false;
    struct curl_slist *headers = NULL;
    headers = curl_slist_append(headers, "Accept: Agent-007");
    curl = curl_easy_init();    // 初始化
    if (curl)
    {
     	
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);// 改协议头
        curl_easy_setopt(curl, CURLOPT_URL,"http://www.baidu.com");
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ReadHandler); //将返回的http头输出到fp指向的文件
	    curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
	    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, HandHandler); //将返回的html主体数据输出到fp指向的文件
	    res = curl_easy_perform(curl);   // 执行
   		if(res!=0)
		{
     
			printf("http access fail!\n");
		}
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
        fclose(fp);
        return true;
    }
}
bool postUrl(char *filename)
{
     
    CURL *curl;
    CURLcode res;
    FILE *fp;
    if ((fp = fopen(filename, "w")) == NULL)
        return false;
    curl = curl_easy_init();
    if (curl)
    {
     
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "&logintype=uid&u=xieyan&psw=xxx86");    // 指定post内容
        curl_easy_setopt(curl, CURLOPT_URL, " http://mail.sina.com.cn/cgi-bin/login.cgi ");   // 指定url
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
        res = curl_easy_perform(curl);
        curl_easy_cleanup(curl);
    }
    fclose(fp);
    return true;
}
int main(void)
{
     
    curl_global_init(CURL_GLOBAL_ALL);
    getUrl("./get.html");
    postUrl("./post.html");
    curl_global_cleanup();
}

添加动态库路径
export LD_LIBRARY_PATH="/home/sh/Desktop/mycurl/curl-7.71.1/_install/lib"
编译 -I为包含头文件路径 -lxxx为动态库名称libxxx.so -L为动态库所在路径
gcc mycurl.c -I /home/sh/Desktop/mycurl/curl-7.71.1/_install/include -lcurl -L /home/sh/Desktop/mycurl/curl-7.71.1/_install/lib -o mycurl

你可能感兴趣的:(linux,http)