原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/2019/0917/644.html
前言
libevent和libcurl都是功用强大的开源库;libevent主要完成效劳器,包含了select、epoll等高并发的完成;libcurl完成了curl命令的API封装,主要作为客户端。
一、常州游戏开发培训curl的两种运用办法
1、命令行形式
所谓命令行形式,就是直接linux的命令行直接能够执行的curl命令,curl能够做很多事情,我主要引见作为客户端发送xml和json数据,由于命令行形式十分要留意格式问题!
(1)发送xml格式数据
格式如下:
复制代码
echo '<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:itsm="http://itsm.soa.csg.cn/">
<soapenv:Header xmlns:auth="http://itsm.soa.csg.cn/">
local_admin
local_admin
1
测试虚拟机181106
11.11.22.23
设备帐户
administrator
'|curl -X POST -H 'Content-type:text/xml' -d @- http://10.94.1.167:80/ITSMWebServer/itsm
复制代码
阐明:
echo后面跟的是手机App外包xml格式数据,格式普通都是跟第三方平台商定好的,不能发这种格式,接纳又是另一种格式,那没法解析了,都要提早商定好的!
中间是“|”管道符,将echo的输出作为curl的输入
POST 阐明是post恳求
-H 携带的音讯头
最后的url,是要发送的地址
(2)发送json格式数据
格式如下:
curl -H "Content-Type:application/json" -H "appName:spvas" -H "password:123123" -H "pswdHashType:SHA1" -X POST -k -g -d '{"param":[{"objectID":112,"type":1,"operate":1,"operatorID":100,"result":0,"time":1539941168,"policytype":0}]}' http://172.16.1.21:9999/rest/spvas/objChange.do
阐明:
-H 仍然是音讯头
-d 后面是json格式的数据了
2、libcurl库运用
1、装置
想要运用libcurl库,首先需求先装置,装置参考我的这篇博客写的很细致:https://www.cnblogs.com/liudw-0215/p/9917422.html
2、运用libcurl的API
主要就是调用libcurl库的API接口,下面引见的http的POST恳求,libcurl很多接口,不能逐个引见,需求时能够再去查找。
(1)初始化curl句柄
CURL* curl = NULL;
curl = curl_easy_init();
(2)设置curl的url
curl_easy_setopt(curl, CURLOPT_URL, "http://172.16.1.96:7777/login");
(3)开启post恳求开关
curl_easy_setopt(curl, CURLOPT_POST, true);
(4)添加post数据
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_str);
(5)设定一个处置效劳器响应的回调函数
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, deal_response);
(6)给回调函数传送一个形参
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData);
(7)向效劳器发送恳求,等候效劳器的响应
res = curl_easy_perform(curl);
3、总体代码
App开发培训客户端总体代码如下:
复制代码
//
// Created by ldw on 2018/11/8.
//
#include "cJSON.h"
#include <curl/curl.h>
#include<string.h>
#define RESPONSE_DATA_LEN 4096
//用来接纳效劳器一个buffer
typedef struct login_response_data
{
login_response_data() {
memset(data, 0, RESPONSE_DATA_LEN);
data_len = 0;
}
char data[RESPONSE_DATA_LEN];
int data_len;
}response_data_t;
//处置从效劳器返回的数据,将数据拷贝到arg中
size_t deal_response(void *ptr, size_t n, size_t m, void *arg)
{
int count = m*n;
response_data_t *response_data = (response_data_t*)arg;
memcpy(response_data->data, ptr, count);
response_data->data_len = count;
return response_data->data_len;
}
#define POSTDATA "{\"username\":\"gailun\",\"password\":\"123123\",\"driver\":\"yes\"}"
int main()
{
char *post_str = NULL;
CURL* curl = NULL;
CURLcode res;
response_data_t responseData;//特地用来寄存从效劳器返回的数据
//初始化curl句柄
curl = curl_easy_init();
if(curl == NULL) {
return 1;
}
//封装常州网站开发培训一个数据协议
/*
====给效劳端的协议====
http://ip:port/login [json_data]
{
username: "gailun",
password: "123123",
driver: "yes"
}
*
*
* */
//(1)封装一个json字符串
cJSON *root = cJSON_CreateObject();
cJSON_AddStringToObject(root, "username", "ldw");
cJSON_AddStringToObject(root, "password", "123123");
cJSON_AddStringToObject(root, "driver", "yes");
post_str = cJSON_Print(root);
cJSON_Delete(root);
root = NULL;
//(2) 向web效劳器 发送http恳求 其中post数据 json字符串
//1 设置curl url
curl_easy_setopt(curl, CURLOPT_URL, "http://172.16.1.96:7777/login");
//客户端疏忽CA证书认证 用于https跳过证书认证
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
//2 开启post恳求开关
curl_easy_setopt(curl, CURLOPT_POST, true);
//3 添加post数据
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_str);
//4 设定一个处置效劳器响应的回调函数
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, deal_response);
//5 给回调函数传送一个形参
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData);
//6 向效劳器发送恳求,等候效劳器的响应
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
return 1;
}
curl_easy_cleanup(curl);
//(3) 处置效劳器响应的数据 此刻的responseData就是从效劳器获取的数据
/*
//胜利
{
result: "ok",
}
//失败
{
result: "error",
reason: "why...."
}
*
* */
//(4) 解析效劳器返回的json字符串
//cJSON *root;
root = cJSON_Parse(responseData.data);
cJSON *result = cJSON_GetObjectItem(root, "result");
if(result && strcmp(result->valuestring, "ok") == 0) {
printf("data:%s\n",responseData.data);
//登陆胜利
return 0;
}
else {
//登陆失败
cJSON* reason = cJSON_GetObjectItem(root, "reason");
if (reason) {
//已知错误
return 1;
}
else {
//未知的错误
return 1;
}
return 1;
}
return 0;
}
复制代码
这是客户端的总体代码,但是还无法测试,由于没有效劳端,下面会引见用libevent库来搭建http的效劳端;由于数据格式是json,所以用到了cJSON,能够到我的github上停止下载,编译命令:g++ login.cpp cJSON.cpp -o login -lcurl
二、libevent库
1、装置
libevent仍然是开源库,运用之前仍然需求装置,装置参考我的这篇博客写的很细致:https://www.cnblogs.com/liudw-0215/p/9917422.html
2、搭建http效劳器
装置之后,就能够运用了,主要都是调用libcurl库的API函数,main函数如下:
复制企业培训代码
int main(int argc, char *argv[]) {
//自定义信号处置函数
signal(SIGHUP, signal_handler);
signal(SIGTERM, signal_handler);
signal(SIGINT, signal_handler);
signal(SIGQUIT, signal_handler);
//默许参数
char *httpd_option_listen = "0.0.0.0";
int httpd_option_port = 7777;
int httpd_option_daemon = 0;
int httpd_option_timeout = 120; //in seconds
//获取参数
int c;
while ((c = getopt(argc, argv, "l:p:dt:h")) != -1) {
switch (c) {
case 'l' :
httpd_option_listen = optarg;
break;
case 'p' :
httpd_option_port = atoi(optarg);
break;
case 'd' :
httpd_option_daemon = 1;
break;
case 't' :
httpd_option_timeout = atoi(optarg);
break;
case 'h' :
default :
show_help();
exit(EXIT_SUCCESS);
}
}
//判别能否设置了-d,以daemon运转
if (httpd_option_daemon) {
pid_t pid;
pid = fork();
if (pid < 0) {
perror("fork failed");
exit(EXIT_FAILURE);
}
if (pid > 0) {
//生成子进程胜利,退出父进程
exit(EXIT_SUCCESS);
}
}
/* 运用libevent创立HTTP Server */
//初始化event API
event_init();
//创立一个http server
struct evhttp *httpd;
httpd = evhttp_start(httpd_option_listen, httpd_option_port);
evhttp_set_timeout(httpd, httpd_option_timeout);
//也能够为特定的URI指定callback
evhttp_set_cb(httpd, "/", httpd_handler, NULL);
evhttp_set_cb(httpd, "/login", login_handler, NULL);
//循环处置events
event_dispatch();
evhttp_free(httpd);
return 0;
}
复制代码
3、测试http效劳
启动效劳端
从我的github上下载之后,http效劳在libcurl/http_server/这个目录,写Makefile,然后直接make就能够了,如下:
make之后生成了server,执行:./server,启动效劳
启动常州软件技术培训客户端
在libcurl/login/这个目录,执行:g++ login.cpp cJSON.cpp -o login -lcurl,停止编译,生成login,启动客户端:./login,客户端运转结果,如下:
效劳端响应结果,如下:
至此,完成了演示,用libcurl和libevent搭建的http效劳器与客户端,没有问题。是不是觉得到此就完毕了,才没有呢?下面,将要引见https效劳器,那为什么要用https效劳器呢?跟随我找到谜底吧!
4、搭建https效劳器
(1)https引见
http传输过程都是明文传输,很不平安;就产生https,停止加密传输,但加密过程并没有那么简单,如下图所示:
阐明:
主要阅历了两个阶段:
非对称加密过程
经过公钥、私钥和CA证书,停止考证,最终取得会话密钥
对称加密过程
可能会想?直接都用非对称加密得了,为啥用对称加密?由于非对称效率很低,所以要用对称加密!
用非对称过程得到的密钥,对数据停止加密然后传输。
(2)https效劳器完成
libevent库应该从2.1版本之后才支持https的,所以在2.1之前的版本还要单独装置openssl!
mian函数如下:
复制代码
int main (int argc, char **argv)
{
/*OpenSSL 初始化 */
common_setup ();
if (argc > 1) {
char *end_ptr;
long lp = strtol(argv[1], &end_ptr, 0);
if (*end_ptr) {
fprintf(stderr, "Invalid integer\n");
return -1;
}
if (lp <= 0) {
fprintf(stderr, "Port must be positive\n");
return -1;
}
if (lp >= USHRT_MAX) {
fprintf(stderr, "Port must fit 16-bit range\n");
return -1;
}
serverPort = (unsigned short)lp;
}
/* now run http server (never returns) */
return serve_some_http ();
}
复制代码
(3)测试https效劳器
启动效劳端
从我的github上下载之后,http效劳在libcurl/https_server/这个目录,写Makefile,然后直接make就能够了;
启动客户端
修正http的客户端就能够了,如下:
curl_easy_setopt(curl, CURLOPT_URL, "https://172.16.1.96:8080/login");
//客户端疏忽CA证书认证 用于https跳过证书认证
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
阐明:
在http后面加上“s”;再加上跳过证书认证,就能够了
上篇:上一篇:织梦dedecms文章页加转载链接的办法
下篇:下一篇:C/C++完成HTTPS通讯(抓取百度页面)