Linux C语言编程-Linux网络通信--Linux上使用curl来发送Http协议的报文---知识点总结+实例d

*********************注意:为了保证文章的完整性和全面性,作者会不定期对文章进行更新和修正*********************


1.curl是什么,有什么用?

一下是我自己的一些看法:

(1)curl是什么或者说cUrl是什么:

 1.cURL = c + URL(C语言上的URL工具可以这样理解吧!)
 2.curl是Linux上的一个工具,说白了就是Linux上的用代码写出来的软件,这个软件放在Linux的系统文件夹内,甚至在Linux环境变量添加了这个软件的地址,所以我们只要通过curl的相关命令就可以直接在终端上使用curl这个软件来传输我们想要发送的信息,同时Linux在我们在/usr/include/curl目录之下还有curl编程的相关头文件(根据系统的不同路径可能不同),相应的Linux系统上还装载了curl的相关开发数库Libcurl,那么这样方便了我们在编写程序的时候也可以使用curl工具的相关函数来达到信息传输的目的,当然在没有curl的Linux系统上你也可以在相关的网站上进行下载,装到计算机上。


(2)curl的作用是什么:
    正如我们上面说cURL的作用是用来传输信息的,传输的信息可能会有很多的类型,不仅仅是字符串好比如说文件,当然cURL也考虑到了这一点,所以cURL也支持相当多的协议,这些协议是:FTP、FTPS、HTTP、HTTPS、TFTP、SFTP、Gopher、SCP、Telnet、DICT、FILE、LDAP、LDAPS、IMAP、POP3、SMTP和RTSP,cURL包含的协议大大的简化了编程人员的工作好比如你只需要几个简单的函数调用,就可以完成Http协议下的信息传输而且绝对规范,不仅如此他还自动帮你解析url完成发送,而不用一个个的自己使用socket去实现(cURL的底层也应该是使用socket来实现的)甚至你这样做出来的信息还不一定规范,还不一定能被对面的应用层的函数正确识别和解析

-题外话-:之前使用socket和cURL(使用HTTP协议)来发送字符串数据并接收(使用socket接收),进行了一次对比,发现这两种方法没有本质上的区别,收到的都是字符串!没有错就是字符串!但是cURL的话对比起socket除了主要数据之外还有相当多的附加信息(比如报文头),而socket就自定义性十分强了自己想发什么就发什么


2.使用cURL并且以http协议的形式发送信息的操作流程

curl的使用流程大致是:

(1)建立一个cURL结构体指针或是变量,我们之后要在这个结构体上添加很多的属性,以及信息,这个类似于使用C来操作mysql时,我们初期要建立一个mysqld的句柄
(2)建立一个curl_slist类型的变量的指针或是变量,这个变量的主要的作用是用来保存传输报文的报文头(报文头相当重要,这个报文头中保存了报文的相关信息,如果你不设置这些信息,就有可能使得接受信息的平台的应用层无法正确的识别你的传输的信息,从而使得无法对信息进行拆解)
(3)使用curl_easy_init()函数对我们刚刚建立的cURL结构体进行初始化
(4)使用curl_slist_append()函数对我们建立的报文头指针或是变量中添加报文头信息,来完善我们的报文头
(5)使用curl_easy_setopt()函数将属性,传输信息的URL和你要传输的信息添加到我们建立的cURL指针或是变量之中,同时使用这个函数将我们的报文头变量或是指针也添加到cURL指针或是变量中
(6)使用curl_easy_perform()函数来发送信息
(7)使用curl_easy_cleanup()函数来清理我们刚刚已经发送的cURL指针


3.相关函数的介绍

**注意:我们在编写使用cURL工具的程序的时候我们一般都要引用<curl/curl.h>这个头文件,因为curl.h中保存函数的实现库并不是gcc自带的标准库,所以我们在使用makefile和gcc来编译程序的时候一定要连接cURL的自带的静态库Libcurl,在写makefile的时候一定要加上-lcurl

**注意: 使用的cURL的版本为7.15.5


(1)curl_easy_init() 函数

函数原型:

    #include <curl/curl.h>

    CURL* curl_easy_init()

返回值:CURL*

相关介绍:

(1)参数:无
(2)函数作用:这个函数返回一个初始化好的CURL类型的指针,其实就是初始化cURL结构体,以便给后边的相关函数添加属性和其他内容

 

(2)curl_slist_append()函数

函数原型:

    #include <curl/curl.h>

    struct curl_slist* curl_slist_append(struct curl_slist* list, const char* string)

返回值:返回一个添加好属性string的报文头结构体

相关介绍:

(1)参数:1.list(这是一个curl_slist类型的结构体指针,这个结构体的作用就是保存我们的报文头)
                 2.string(字符串常量,这个常量的就是我们要添加的报文头,注意是常量)
(2)函数作用:向报文头结构体指针中添加报文头内容

(3)curl_esay_setopt()函数

函数原型:

    #include <curl/curl.h>

    CURLcode curl_esay_setopt(CURL *handle, CURLoption option, parameter);

返回值:CURLcode(这是一个枚举类型的变量,里面保存了相当多的值,返回值会取值为他们中的一个)

相关介绍:

(1)参数:1.handle(cURL句柄,也就是我们建立好的cURL结构体,而且是指针)
                 2.option(我们要设置的相关属性)
                 3.parameter(属性的相关的值)
(2)函数作用:用来向我们建立的cURL句柄中添加属性,报文头,发送报文,以及发送报文的URL
(3)注意:这里看一下option可以取得的值(这里我们只列举部分常用的):
     1.CURLOPT_HTTPHEADER(这个属性是给cURL结构体添加报文头,parameter取值为报文头)
     2.CURLOPT_URL(这个属性是给cURL结构体添加发送信息的url,parameter取值为url字符串,注意这个url前面一定要加上协议,因为curl判断使用什么协议来发送数据就来自parameter的前端的协议)
     3.CURLOPT_TIMEOUT(这个属性是给cURL结构体添加发送的超时的时间,parameter取值为超时时间,单位为秒)
     4.CURLOPT_POSTFIELDS(这个属性是给cURL结构体设置要发送的数据,parameter取值为要发送的数据)
     5.CURLOPT_WRITEFUNCTION(这个属性是给cURL结构体设置当cURL成功发送数据,并且取得返回数据,由那个函数来处理得到的返回报文, parameter设置为处理返回结果的函数的名称)
     6.CURLOPT_POST(这个属性是给CURL结构体设置发送方式,parameter设置为1表示使用post方式发送,0表示使用get方式发送)
     7.CURLOPT_HEADER(这个属性,如果parameter设置为非0,表示返回的数据中的报文头也要一起给CURLOPT_WRITEFUNCTION属性中设置的处理函数进行处理)

*CURLOPT_WRITEFUNCTION中设置处理返回信息的函数的函数的格式只能定义为:
size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata);
参数介绍:ptr(指向cURL返回的数据的指针), size(cURL返回数据的单个的大小),nmemb(cURL返回数据的总个数),stream(一个文件指针,将返回的数据指向某个文件中,这个参数由CURLOPT_WRITEDATA定义)


(4)curl_easy_perform()函数

函数原型:

    #include <curl/curl.h>

   CURLcode curl_easy_perform(CURL* easy_handle)

返回值:CURLcode(这是一个枚举类型的变量,里面保存了相当多的属性,当函数执行成功时CURLcode会取值为CURLE_OK)

相关介绍:

(1)参数:1.easy_handle(我们使用curl_esay_setopt()函数设置好属性的cURL句柄)

(2)函数作用:执行我们设置好属性的cURL句柄,其实就是发送信息


相关实例代码:

CURL* curl;                    //curl的结构体,指向建立起来的curl
CURLcode res;                  //定义res来保存Curl/http的请求的返回码

curl = curl_easy_init();                //初始化一个curl
struct curl_slist* headers = NULL;      //定义Curl的头部结构体
	
//---------------------给curl要发送的报文添加头部----------------------
headers = curl_slist_append(headers, "Accept:application/json");            //表示本地cURL接受报文为json
headers = curl_slist_append(headers, "Content-Type:application/json");      //请求我们发送的报文为json,注意这里一定要说明自己发送的信息为JSON类型的,否则对方使用的应用层函数可能无法正确的识别解析
headers = curl_slist_append(headers, "charset:utf-8");                      //表示我们发送的报文的编码格式为utf-8类型的格式
//---------------------------------------------------------------------
	
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);            //给cURL结构体添加我们刚刚组成好的头部
curl_easy_setopt(curl, CURLOPT_URL, Url);                       //向cURL结构体中设置要发送请求的url 
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60);                    //设置cURL的等待时间为60s,过了60s就超时
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, updata->Buffer);     //向cURL结构体中设置我们要发送的数据updata.buffer
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, getData);         //向cURL返回的数据给我们定义的getData函数进行处理
curl_easy_setopt(curl, CURLOPT_POST, 1);                        //CURLOPT_POST:设置为非0(一般使用1)表示本次操作为POST,为0表示GET方式
//curl_easy_setopt(curl, CURLOPT_HEADER, 1);                    //CURLOPT_HEADER:设置为非0表示将返回的报文的报文头和报文体一起传给WRITEFUNCTION定义的函数(也就是getData)    
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);              //CURLOPT_FOLLOWLOCATION:设置为非0,响应头信息Location
//curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/Users/zhu/CProjects/curlposttest.cookie");        //获得cookie数据
	
res = curl_easy_perform(curl);             //执行cURL中保存的操作,res中保存了执行返回的状态结果(使用int来保存枚举类的值)
curl_easy_cleanup(curl);                   //清除请求结构体
	
if(res != CURLE_OK)                        //如果是curl执行的结果为不成功    
{    
    PrintLog(__FILE__, __LINE__, project, "OptionPostData:请求http失败\n");     
    switch(res)                            //对错误的结果进行判断    
    {    
        case CURLE_UNSUPPORTED_PROTOCOL:   //cURL-不支持的协议(协议由URL的头部指定,因为我们要用发送http协议发送数据,URL头部协议使用http://)	
        {    
            return CL_UnSupport; 												
        }    
        case CURLE_COULDNT_CONNECT:        //cURL-不能连接到remote主机或者代理
        {    
            return CL_CntConnect;  
        }    
        case CURLE_HTTP_RETURNED_ERROR:    //cURL-Http不返回错误
        {    
            return CL_NRHttp;  
        }    
        case CURLE_READ_ERROR:             //cURL-本地文件错误
        {    
            return CL_NRead;  
        }    
        default:                           //其他错误(这里并没有定列举所有的错误类型)
        {    
            return CL_UnKError;  
        }    
    }     
}  
else  
{  
    return 0;
}

//定义处理cURL返回数据的getData函数
size_t getData(void *ptr, size_t size, size_t nmemb, void *stream)
{
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值