相关文章推荐

1.     前言

Linux下的http请求有许多种方式,其中curl库是C语言封装的一个强大的库,使用curl比封装socket更加方便。cJSON是一个小型的json封装库,可以把数据封装成json格式。本文介绍了这两种技术,并通过此技术完成了Linux下的http请求,同时把代码封装到quagga下,quagga运行时可以正常创建数据到ONOS。

2.     Linux 下http请求实现

2.1.    curl 简介

curl命令是一个功能强大的网络工具,它能够通过http、ftp等方式下载文件,也能够上传文件。curl命令使用了libcurl库来实现,libcurl库常用在C程序中用来处理HTTP请求,curlpp是libcurl的一个C++封装,这几个东西可以用在抓取网页、网络监控等方面的开发,而curl命令可以帮助来解决开发过程中遇到的问题。本文档就是使用curl完成http请求。

2.1.1.    全局初始化

应用程序在使用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。它们只能被调用一次。

2.1.2.    easy interface

libcurl中被称为easy interface的api函数,所有这些函数都是有相同的前缀:curl_easy 。

要使用easyinterface,首先必须创建一个easy handle,easy handle用于执行每次操作。基本上,每个线程都应该有自己的easy handle用于数据通信(如果需要的话)。千万不要在多线程之间共享同一个easy handle。下面的函数用于获取一个easy handle:

CURL *easy_handle =curl_easy_init();

在easyhandle上可以设置属性和操作(action)。easy handle就像一个逻辑连接,用于接下来要进行的数据传输。

使用 curl_easy_setopt函数可以设置easy handle的属性和操作,这些属性和操作控制libcurl如何与远程主机进行数据通信。一旦在easy handle中设置了相应的属性和操作,它们将一直作用该easyhandle。也就是说,重复使用easy hanle向远程主机发出请求,先前设置的属性仍然生效。

easy handle的许多属性使用字符串(以\0结尾的字节数组)来设置。通过curl_easy_setopt函数设置字符串属性时,libcurl内部会自动拷贝这些字符串,所以在设置完相关属性之后,字符串可以直接被释放掉(如果需要的话)。

后面章节会根据http的get和post接口对常用的easy handle函数进行说明。

2.2.    cJSON 简介

cJSON是在C语言中解析JSON的开源库,在cJSON中,一个key-value键值对被解析并存放在一个cJSON结构体变量中,其value取值集为:FALSE,TRUE,NULL,NUMBER,STRING,OBJECT,ARRAY。cJOSN库,仅有两个文件cJSON.c和cJSON.h。

2.2.1. cJSON 使用说明

下面使用cJSON组装以下json数据

"mac":  "46:E4:3C:A4:11:12",

"vlan": "-1",

"ipAddresses":  ["222.222.233.2"],

"location": {

"elementId":    "of:0000001e08000fe3",

"port": "31"

代码如下:

// 创建一个 object

cJSON *root =cJSON_CreateObject();

cJSON_AddItemToObject(root,"mac",cJSON_CreateString("46:E4:3C:A4:13:12"));

cJSON_AddStringToObject(root,"vlan","-1");

cJSON*array = NULL;

cJSON_AddItemToObject(root,"ipAddresses",array=cJSON_CreateArray());

cJSON_AddItemToArray(array,cJSON_CreateString("192.168.10.2"));

// 创建一个子 object ,将此 object 添加到 root

cJSON*location = NULL;

cJSON_AddItemToObject(root,"location",location=cJSON_CreateObject());

cJSON_AddStringToObject(location,"elementId","of:0000001e08000fe3");

cJSON_AddStringToObject(location,"port","31");

// json 结构格式化到缓冲区

char*buf = cJSON_Print(root);

// 执行 http 请求函数

http_client_thttp_read_client;

http_client_read_init(&http_read_client,temp, buf);

// 数据使用完之后,把内存释放掉

cJSON_Delete(json);

free(buf);

2.3.    http 的post请求

int http_client_read_init(http_client_t*http_client, const char *url, char *szJsonData)

if (!url) {

return -1;

// 初始化 libcurl ,设置默认参数

CURLcode return_code = curl_global_init(CURL_GLOBAL_ALL);

if (CURLE_OK != return_code) {

printf("initlibcurl failed.\n");

return -1;

// 获取 easy handle

http_client->handle = curl_easy_init();

if (!http_client->handle) {

return -1;

// 通过 CURLOPT_URL 属性设置 url

curl_easy_setopt(http_client->handle, CURLOPT_URL, url);

// 通过 CURLOPT_HTTPHEADER 定义 http 消息的 header

struct curl_slist *plist = NULL;

plist = curl_slist_append(plist, "Content-Type:application/json");

curl_easy_setopt(http_client->handle, CURLOPT_HTTPHEADER, plist);

printf("Thejson is: %s\n", szJsonData);

// 通过 CURLOPT_POSTFIELDS 设置要 POST 的数据

curl_easy_setopt(http_client->handle,CURLOPT_POSTFIELDS, szJsonData);

// 通过 CURLOPT_USERPWD 属性来设置用户名与密码。参数是 ”user:password “ 的字符串

curl_easy_setopt(http_client->handle,CURLOPT_USERPWD, "karaf:karaf");

// 使用 curl_easy_perform 执行上传数据

curl_easy_perform(http_client->handle);

// 任务执行结束使用 curl_easy_cleanup 把内存释放

curl_easy_cleanup(http_client->handle);

return 0;

2.4.    http 的get请求

int http_client_init(http_client_t*http_client, const char *url, write_cb_t *write_data, void *userp)

if (!url) {

return -1;

// 初始化 libcurl ,设置默认参数

CURLcode return_code;

return_code= curl_global_init(CURL_GLOBAL_ALL);

if (CURLE_OK != return_code) {

printf("initlibcurl failed.\n");

return -1;

//获取easy handle

http_client->handle = curl_easy_init();

if (!http_client->handle) {

return -1;

// 通过 CURLOPT_URL 属性设置 url

curl_easy_setopt(http_client->handle,CURLOPT_URL, url);

// 注册回调函数 write_cb ,回调函数将会在接收到数据的时候被调用

curl_easy_setopt(http_client->handle, CURLOPT_WRITEFUNCTION, write_data);

// 通过 CURLOPT_USERPWD 属性来设置用户名与密码。参数是 ”user:password “ 的字符串

curl_easy_setopt(http_client->handle,CURLOPT_USERPWD, "karaf:karaf");

if (userp) {

// 设置写数据的变量

curl_easy_setopt(http_client->handle, CURLOPT_WRITEDATA, userp);

// 使用 curl_easy_perform 执行上传数据

curl_easy_perform(http_client->handle);

// 任务执行结束使用 curl_easy_cleanup 把内存释放

curl_easy_cleanup(http_client->handle);

return 0;

// 回调函数,将接收到的数据保存到本地文件中,同时显示在控制台上。

static size_t write_data(void *buf, size_tsize, size_t nmemb, void *userp)

FILE *fp = (FILE *)userp;

size_t return_size = fwrite(buf, size, nmemb, fp);

printf("write_data: %ld, return_size: %ld\n", nmemb,return_size);

return return_size;

2.5.    http的del请求

// 获取 easy handle

http_client->handle = http_client_init();

if (!http_client->handle) {

return -1;

// 通过 CURLOPT_URL 属性设置 url

curl_easy_setopt(http_client->handle, CURLOPT_URL, url);

// 设置 http 发送的内容类型为 JSON

struct curl_slist *plist = NULL;

//plist = curl_slist_append(plist, "Content-Type:application/json");

curl_easy_setopt(http_client->handle,CURLOPT_HTTPHEADER, plist);

// 设置要 POST JSON 数据

//curl_easy_setopt(http_client->handle, CURLOPT_POSTFIELDS,szJsonData);

curl_easy_setopt(http_client->handle,CURLOPT_CUSTOMREQUEST, "DELETE");

curl_easy_setopt(http_client->handle,CURLOPT_USERPWD, "karaf:karaf");

2.6.    编译并执行

代码完成之后,使用gcc运行时需要带如下参数:

gcc -o http_client http_client.ccJSON.c -lcurl –lm

编译之后开始运行

./http_client

通过抓包可以看到http报文

注意事项:

1.  -lcurl是链接curl库,如果运行报如下错误:

mlogc.c:32:23: error: curl/curl.h: No such fileor directory

mlogc.c:1091: error: expected ‘)’ before ‘*’token

mlogc.c: In function ‘logc_init’:

则需要安装如下依赖包:libcurl-dev, libcurl-devel

centOS上安装依赖包:

yum install libcurl-dev libcurl-devel

2.   –lm是链接math的库,由于cJSON需要调用math库,如果不添加会报如下错误:

3.   如果有多个方法例如:get/post/delete等用到的URL一样,需要把如下代码,包含URL的头部注释掉,否则报文发布出去。

// 设置 http 发送的内容类型为 JSON

struct curl_slist *plist = NULL;

//plist = curl_slist_append(plist, "Content-Type:application/json");

curl_easy_setopt(http_client->handle,CURLOPT_HTTPHEADER, plist);

1.前言Linux下的http请求有许多种方式,其中curl库是C语言封装的一个强大的库,使用curl比封装socket更加方便。cJSON是一个小型的json封装库,可以把数据封装成json格式。本文介绍了这两种技术,并通过此技术完成了Linux下的http请求,同时把代码封装到quagga下,quagga运行时可以正常创建数据到ONOS。2.Linux下http请求 int create_tcp_socket(); char *get_ip(char *host); char *build_get_query(char *host,char *page); void usage(); #define HOST
02 Linux 下使用libcurl( C语言 )来 实现 http请求 (数据保存至内存)(这里可以让你深入了解realloc函数) 这篇是从官网的例子中学习的,里面有非常多例子让我们参考。 libcurl/c/example 上一篇我们讲到网站服务器的响应保存到文件,这篇是保存到内存的。 1 c语言 中realloc()函数的作用 c语言 中realloc()函数解析 realloc作用:调整已有的内存。//非常重要的理解,并不是malloc一样开辟指定大小的内存。 //realloc作用:调整已有的
超文本传输协议是一种用于分布式、协作式和超媒体信息系统的应用层协议。 HTTP 是一个客户端终端(用户)和服务器端(网站)请求和应答的标准(一般基于TCP)。客户端发起一个 HTTP请求 到服务器上指定端口(默认端口为80),这个客户端被称为用户代理程序(user agent)。应答服务器被称为源服务器(origin server)。在用户代理和源服务器中间可能存在多个“中间层”,比如代理服务器、网关或者隧道(tunnel) HTTP 可以在任何互联网协议上,或其他网络上 实现 HTTP 假定其下层
Linux C语言 和Java程序可以通过 HTTP请求 进行通信。而为了保证通信的安全和加密性,我们通常会使用 HTTP S请求。那么这个过程该如何 实现 呢? 首先,我们需要理解 HTTP请求 HTTP S请求的基本原理。 HTTP 协议是基于明文传输的,容易被恶意攻击者截获数据包,窃取敏感信息。为了避免这种情况的发生, HTTP S协议在 HTTP 上添加了SSL/TLS协议,将数据进行加密传输,保障了数据的安全性。因此,使用 HTTP S请求进行通信是非常重要的。 在 Linux C语言 中,我们可以使用第三方库openssl来 实现 HTTP S请求的功能。具体 实现 方式为: 1. 导入openssl库,并在代码中初始化相关的参数,如证书路径、私钥等。 2. 创建一个 HTTP S连接,并指定服务器地址和端口号。 3. 设置连接中的参数和加密类型,以确保连接的安全性。 4. 发送请求以及相关的参数。 5. 接收响应,并对响应进行处理和解析。 在Java中,则可以使用 Http URLConnection或 Http Client等内置的库进行 HTTP / HTTP S请求的 实现 。具体 实现 方式为: 1. 创建URL对象,并设置请求的目标地址。 2. 打开连接,并设置请求的相关参数,如请求方式、请求参数、请求头等。 3. 发送请求,并接收响应。对响应进行解析和处理,可采用JSON、XML等格式。 总之,无论是 Linux C语言 还是Java程序,都可以通过 HTTP S请求进行通信,并保障数据的安全性和加密性。相比起 HTTP HTTP S是一种更为安全和可靠的通信协议,可以更好地满足商业和技术的需求。
你俩鸡同鸭讲,你看他的代码第一二种的顺序和你的不一样,他的第一种是你的第二种。 总结:你说的keySet效率低,甚至会比entrySet方式慢一倍,他的测试结果反而是keySet效率比entrySet快不少。他自己也没有仔细看,这不叫说法不准确,而是叫测试结果和说法矛盾。 另外你看他的entrySet().iterator()方式结果和keySet方式效率接近,这两个却都比entrySet方式快不少。是不是和你说的很不一样,那怎么解释呢,什么原理呢? nginx中用到的kill命令 get嘤嘤嘤: 感谢博主分享,一整篇满满的干货,深度好文必须三连。欢迎您来我的博客指点。*:ஐ٩(๑´ᵕ`)۶ஐ:* 有状态的bean和无状态的bean的区别 CrAcKeR-1: 可以这么理解? 比如在类定义时成员变量的时候都使用final关键字所定义的,此时这个Bean交给容器管理是一个无状态Bean
 
推荐文章