Linux智能家居项目

一、C语言的面向对象编程思想-OOP(Object Oriented Programming)

1、C语言中的“类”

OOP1.C

#include <stdio.h>

struct Animal{//类似与其他语言的抽象类概念
	char name[128];
	int age;
	char sex;
	void (*peat)();
	void (*pbeat)();
};

void dogEat()
{
	printf("狗吃屎\n");
}

void catEat()
{
	printf("猫吃鱼\n");
}

void personEat()
{
	printf("人吃米\n");
}

void dogBeat()
{
	printf("咬你小弟弟\n");
}

void catBeat()
{
	printf("抓你小弟弟\n");
}

void personBeat()
{
	printf("猴子偷桃\n");
}

int main()
{
	struct Animal dog;//类的具象化表现,类的实例化
	struct Animal cat;
	struct Animal person;

	dog.peat=dogEat;
	cat.peat=catEat;
	person.peat=personEat;

	dog.pbeat=dogBeat;
	cat.pbeat=catBeat;
	person.pbeat=personBeat;

	dog.peat();
	cat.peat();
	person.peat();

	dog.pbeat();
	cat.pbeat();
	person.pbeat();


	return 0;
}

OOP2.c 

#include <stdio.h>

struct Animal{//类似与其他语言的抽象类概念
	char name[128];
	int age;
	char sex;
	void (*peat)();
	void (*pbeat)();
};

void dogEat()
{
	printf("狗吃屎\n");
}

void catEat()
{
	printf("猫吃鱼\n");
}

void personEat()
{
	printf("人吃米\n");
}

void dogBeat()
{
	printf("咬你小弟弟\n");
}

void catBeat()
{
	printf("抓你小弟弟\n");
}

void personBeat()
{
	printf("猴子偷桃\n");
}

int main()
{
	struct Animal dog={
		.peat=dogEat,
		.pbeat=dogBeat
	};//类的具象化表现,类的实例化
	struct Animal cat={
		.peat=catEat,
		.pbeat=catBeat
	};
	struct Animal person={
		.peat=personEat,
		.pbeat=personBeat
	};

	//dog.peat=dogEat;
	//cat.peat=catEat;
	//person.peat=personEat;

	//dog.pbeat=dogBeat;
	//cat.pbeat=catBeat;
	//person.pbeat=personBeat;

	dog.peat();
	cat.peat();
	person.peat();

	dog.pbeat();
	cat.pbeat();
	person.pbeat();


	return 0;
}

2、工厂模式

工厂模式(Factory Pattern)是最常用的设计模式之一,这种类型的设计模式属于创建型模式,它提供了一种创建对象的(最佳)方式

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象

好的设计模式是为了代码更容易被人理解,代码的可靠性更高,复用性越强

23种设计模式详解

mainpro.c

#include "Animal.h"
#include <string.h>




struct Animal *find_LinkNode_Byname(struct Animal *phead,char *name)
{
	if(phead == NULL){
		return NULL;
	}
	while(phead !=NULL){
		if(strcmp(phead->name,name) == 0){
			return phead;
		}
		phead = phead->next;
	}
	return NULL;
}





int main()
{
	char buf[128]={0};
	struct Animal *phead =NULL;
	struct Animal *tmp =NULL;
	phead = add_Cat_In_Link(phead);
	phead = add_Dog_In_Link(phead);
	phead = add_Person_In_Link(phead);

	while(1){
		printf("input:Tom,huang,pengkaifan\n");
		scanf("%s",buf);
		tmp = find_LinkNode_Byname(phead,buf);
		if(tmp == NULL){
			printf("name is NULL\n");
			continue;
		}else{
			tmp->peat();
			tmp->pbeat();
		}
		
	}

	
	return 0;
}

Animal.h

#include <stdio.h>

struct Animal{//类似与其他语言的抽象类概念
	char name[128];
	int age;
	char sex;
	void (*peat)();
	void (*pbeat)();
	struct Animal *next;
};

struct Animal *add_Cat_In_Link(struct Animal *phead);
struct Animal *add_Dog_In_Link(struct Animal *phead);
struct Animal *add_Person_In_Link(struct Animal *phead);

cat.c

#include "Animal.h"

void catEat()
{
	printf("cat eat fish\n");
}
void catBeat()
{
	printf("hit your brother\n");
}


struct Animal cat={
		.name="Tom",
		.peat=catEat,
		.pbeat=catBeat
};


struct Animal *add_Cat_In_Link(struct Animal *phead)
{
	if(phead != NULL)
		cat.next=phead;
	return &cat;
}

dog.c

#include "Animal.h"

void dogEat()
{
	printf("dog eat shit\n");
}
void dogBeat()
{
	printf("hit your brother\n");
}


struct Animal dog={
		.name="huang",
		.peat=dogEat,
		.pbeat=dogBeat
};


struct Animal *add_Dog_In_Link(struct Animal *phead)
{
	if(phead != NULL)
		dog.next=phead;
	return &dog;
}

person.c

#include "Animal.h"

void personEat()
{
	printf("person eat rich\n");
}
void personBeat()
{
	printf("hit your brother\n");
}


struct Animal person={
		.name="pengkaifan",
		.peat=personEat,
		.pbeat=personBeat
};


struct Animal *add_Person_In_Link(struct Animal *phead)
{
	if(phead != NULL)
		person.next=phead;
	return &person;
}

二、socket、tcp、http的区别

参考博文:socket,tcp,http区别(史上最全)

1、七层网络模型

七层网络模型简称OSI模型,供一个使各种不同的计算机和网络在世界范围内实现互联的标准框架。
7.应用层:例如HTTP、SMTP、SNMP、FTP、Telnet、SIP、SSH、NFS、RTSP、XMPP、Whois、ENRP
6.表示层:例如XDR、ASN.1、SMB、AFP、NCP
5.会话层:例如ASAP、TLS、SSH、ISO 8327 / CCITT X.225、RPC、NetBIOS、ASP、Winsock、BSD sockets
4.传输层:例如TCP、UDP、RTP、SCTP、SPX、ATP、IL
3.网络层:例如IP、ICMP、IGMP、IPX、BGP、OSPF、RIP、IGRP、EIGRP、ARP、RARP、 X.25
2.数据链路层:例如以太网、令牌环、HDLC、帧中继、ISDN、ATM、IEEE 802.11、FDDI、PPP
1.物理层:例如线路、无线电、光纤、信鸽

从上面七层网络模型可以看到,TCP在传输层,socket在会话层,http在应用层

参考博文:深入浅出-网络七层模型

2、TCP/IP的三次握手

1.客户端发SYN=1,seq=x
2.服务器回SYN=1,ack=x+1,seq=y,ACK=1
3.客户端发SYN=1,ack=x+1,seq=y+1,ACK=1

三次握手其实就是通过发数据及数据+1的方式使客户端和服务器双方都确认了双方已经通讯上了,就好比打电话:

1、客户端发:你听得到我说话吗?                               

2、服务器回:我听到了,你听得到我说话吗?               

3、我听到了,我们开始通讯吧!     

3、TCP/IP的四次挥手

1.客户端发FIN=1,seq=u
2.服务器回ACK=1,seq=v,ack=u+1 ,                代表收到了,一会回复断开
2.服务器回ACK=1,seq=w,ack=u+1,FIN=1
3.客户端发ACK=1,seq=u+1,ack=w+1

为何TCP/IP断开时需要四次挥手呢,是由于当客户端发起断开请求时,服务器此时可能正在跟别的客户端在通讯,服务器会先发一包数据给客户端,代表断开请求已经收到了,待会再处理断开请求

TCP/IP三次握手,四次挥手详解

4、socket、tcp、http区别

1、socket是通信的基石,是TCP/IP的基本操作单元(最小单位),程序员层面可以理解为TCP/IP的封装,调用接口

2、socket并不是真正意义上的长连接,当两个小时无数据通讯,服务器会每个75S发一次侦测的报文,如果10此侦测报文都无反馈,则断开连接
3、应用层和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务
4、不同的计算机语言不通,无法正常的解析数据,HTTP等应用层协议规定了一种统一的格式(像串口协议一样,格式和速度等),使得数据得以解析


 

三、Http协议详解

参考博文:http协议之libcurl实现

1、http特性

http协议是建立在TCP/IP协议之上的应用层协议,默认端口80,8080

http协议是一种短连接的协议,发送请求至获取数据后即刻断开连接

2、http协议的请求

利用抓包工具httpwatch可以获取报文

http协议的报文传输的是ASCII码,在TCP/IP协议之上,主要分为三部分

请求行、请求头、请求体

请求行包含:请求方式,url,http协议版本等(GET请求POST请求

请求头包含:状态数据,标识数据等等(信息名:信息值 按行分隔)

请求体包含:请求代理端项服务器端,发送的请求数据!

3、http协议的响应

响应包括:响应行、响应头、响应体

响应行包括:协议版本、状态码、状态消息

响应头包括:内容类型,响应主体数据的长度,响应的时间等

响应体包括:响应数据等

4、https

http协议是明文传输的,因此很容易被截取和解析,泄漏个人数据。https协议是在http和tcp之间多添加了一层,进行身份验证和数据加密。

明文: 明文指的是未被加密过的原始数据。
密文:明文被某种加密算法加密之后,会变成密文,从而确保原始数据的安全。密文也可以被解密,得到原始的明文。
密钥:密钥是一种参数,它是在明文转换为密文或将密文转换为明文的算法中输入的参数。密钥分为对称密钥与非对称密钥,分别应用在对称加密和非对称加密上。

对称加密:数据的加密和解密过程用的是同一个钥匙

非对称加密:数据的加密和解密过程用的不是同一个钥匙

四、http协议之libcurl实现

1、libcurl简介

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

libcurl的官网 http://curl.haxx.se/ 

库下载Release 7.71.1 · curl/curl · GitHub

2、libcurl的使用

调用curl_global_init()初始化libcurl

调用curl_easy_init()函数得到 easy interface型指针

调用curl_easy_setopt()设置传输选项

根据curl_easy_setopt()设置的传输选项,实现回调函数以完成用户特定任务

调用curl_easy_perform()函数完成传输任务

调用curl_easy_cleanup()释放内存

3、libcurl库函数详解

CURLcode curl_global_init(long flags);
函数作用:libcurl库全局初始化,只能调用一次,在调用curl_global_cleanup函数后仍然可再用

flags
CURL_GLOBAL_ALL                  //初始化所有的可能的调用。
CURL_GLOBAL_SSL                  //初始化支持 安全套接字层。
CURL_GLOBAL_WIN32            //初始化win32套接字库。
CURL_GLOBAL_NOTHING       //没有额外的初始化。

返回值:返回值为0代表成功
1.CURLE_OK                    任务完成一切都好
2.CURLE_UNSUPPORTED_PROTOCOL    不支持的协议,由URL的头部指定
3.CURLE_COULDNT_CONNECT        不能连接到remote 主机或者代理
4.CURLE_REMOTE_ACCESS_DENIED    访问被拒绝
5.CURLE_HTTP_RETURNED_ERROR    Http返回错误
6.CURLE_READ_ERROR        读本地文件错误


-------------------------------------------------------------------------------------------------------------------------
void curl_global_cleanup(void);
函数作用:释放整个libcurl库占用的内存,相当于文件操作的close函数


-------------------------------------------------------------------------------------------------------------------------
char *curl_version( );
函数作用:打印当前libcurl库的版本

返回值:当前libcurl库版本字符串指针


-------------------------------------------------------------------------------------------------------------------------
CURL *curl_easy_init( );
函数作用:初始化一个CURL的指针,代表一个会话开始了,相应的在调用结束时要用curl_easy_cleanup()函数清理,当调用该函数前还没调用curl_global_init()函数,则curl_global_init()函数将由libcurl库自动调用,所以多线程中最好主动调用curl_global_init()函数,以防止线程中curl_easy_init时多次调用。

返回值:CURL类型指针


-------------------------------------------------------------------------------------------------------------------------
void curl_easy_cleanup(CURL *handle);
函数作用:释放掉CURL指针,与curl_easy_init( )函数搭配使用

handle:CURL指针


-------------------------------------------------------------------------------------------------------------------------
CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);
函数作用:指定让libcurl库执行何种行为

handle:CURL指针

option:
CURLOPT_URL
设置要访问的url,搭配第三个参数parameter使用,parameter为char *

CURLOPT_WRITEFUNCTION
回调函数原型为:size_t function( void *ptr, size_t size, size_t nmemb, void *stream);

给easy handle设置回调函数,此函数将在libcurl接收到数据后被调用,因此函数多做数据保存的功能,如处理下载文件。

CURLOPT_WRITEDATA
如果没有设置CURLOPT_WRITEFUNCTION,只设置了CURLOPT_WRITEDATA,则给默认回调函数传递一个已经打开的文件指针,用于将数据输出到文件里

CURLOPT_HEADERFUNCTION
回调函数原型为 size_t function( void *ptr, size_t size,size_t nmemb, void *stream);
libcurl一旦接收到http 头部数据后将调用该函数

CURLOPT_HEADERDATA
如果没有设置CURLOPT_HEADERFUNCTION,只设置了CURLOPT_HEADERDATA,则给默认回调函数传递一个已经打开的文件指针,用于将数据输出到文件里

CURLOPT_READFUNCTION
回调函数原型为size_t function(void *ptr, size_t size, size_t nmemb,void *stream);
libcurl需要读取数据传递给远程主机时将调用该函数

CURLOPT_READDATA
如果没有设置CURLOPT_READFUNCTION,只设置了CURLOPT_READDATA,则给默认回调函数传递一个已经打开的文件指针,将该文件内数据传输给远程主机


CURLOPT_NOPROGRESS,CURLOPT_PROGRESSFUNCTION,CURLOPT_PROGRESSDATA
跟数据传输进度相关的参数。
CURLOPT_PROGRESSFUNCTION 指定的函数正常情况下每秒被libcurl调用一次,为了使CURLOPT_PROGRESSFUNCTION被调用,CURLOPT_NOPROGRESS必须被设置为false,CURLOPT_PROGRESSDATA指定的参数将作为CURLOPT_PROGRESSFUNCTION指定函数的第一个参数

CURLOPT_TIMEOUT
由于设置传输时间

CURLOPT_CONNECTIONTIMEOUT
设置连接等待时间

CURLOPT_FOLLOWLOCATION
设置重定位URL

CURLOPT_RANGE: CURLOPT_RESUME_FROM
断点续传相关设置。
CURLOPT_RANGE 指定char *参数传递给libcurl,用于指明http域的RANGE头域,例如:
表示头500个字节:bytes=0-499
表示第二个500字节:bytes=500-999
表示最后500个字节:bytes=-500
表示500字节以后的范围:bytes=500-
第一个和最后一个字节:bytes=0-0,-1
同时指定几个范围:bytes=500-600,601-999
CURLOPT_RESUME_FROM 传递一个long参数给libcurl,指定你希望开始传递的偏移量。

CURLOPT_HTTPHEADER
改协议头



parameter:这个参数 既可以是个函数的指针,也可以是某个对象的指针,也可以是个long型的变量.它用什么这取决于第二个参数


-------------------------------------------------------------------------------------------------------------------------
CURLcode curl_easy_perform(CURL *handle);
函数作用:让libcurl库指定的各种行为执行起来

返回值:返回0代表成功
1.CURLE_OK             任务完成一切都好
2.CURLE_UNSUPPORTED_PROTOCOL    不支持的协议,由URL的头部指定
3.CURLE_COULDNT_CONNECT        不能连接到remote 主机或者代理
4.CURLE_REMOTE_ACCESS_DENIED    访问被拒绝
5.CURLE_HTTP_RETURNED_ERROR    Http返回错误
6.CURLE_READ_ERROR        读本地文件错误


-------------------------------------------------------------------------------------------------------------------------
const char *curl_easy_strerror(CURLcode errornum) 
函数作用:获取详细的错误字符串

返回值:错误字符串

编译下面代码需要链接库

gcc demo1.c -I ./curl-7.71.1/_install/include/ -L ./curl-7.71.1/_install/lib/ -lcurl

-I ./curl-7.71.1/_install/include/         链接头文件路径

-L ./curl-7.71.1/_install/lib/                链接库文件路径

-lcurl                                                链接库名

#include <stdio.h>
#include <curl/curl.h>
#include <stdbool.h>
bool getUrl(char *filename,char *filename1)
{
	CURL *curl;
	CURLcode res;
	char buf[1024*10] = {0};
	FILE *fp;
	FILE *fp1;
	if ((fp = fopen(filename, "w+")) == NULL)  // 返回结果用文件存储
		return false;
	if ((fp1 = fopen(filename1, "w+")) == NULL)  // 返回结果用文件存储
		return false;
	struct curl_slist *headers = NULL;
	headers = curl_slist_append(headers, "Accept: Agent-007");
	curl = curl_easy_init();    // 初始化
	if (curl !=NULL){
		printf("curl is %p\n",curl);
		//curl_easy_setopt(curl, CURLOPT_PROXY, "10.99.60.201:8080");// 代理
		curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);// 改协议头
		curl_easy_setopt(curl, CURLOPT_URL,"http://www.baidu.com");
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); //将返回的http头输出到fp指向的文件
		curl_easy_setopt(curl, CURLOPT_HEADERDATA, fp1); //将返回的html主体数据输出到fp指向的文件
		res = curl_easy_perform(curl);   // 执行
		

		curl_slist_free_all(headers);
		curl_easy_cleanup(curl);
		
		fseek(fp,0,SEEK_SET);
		fread(buf,sizeof(buf),1,fp);	
		printf("%s\n",buf);
		fclose(fp);
		
		if (res != 0) {
			printf("error");
			return false;
		}
		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_COOKIEFILE, "/tmp/cookie.txt"); // 指定cookie文件
		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "&logintype=uid&u=xieyan&psw=xxx86");    // 指定post内容
		//curl_easy_setopt(curl, CURLOPT_PROXY, "10.99.60.201:8080");
		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("/tmp/get.html","/tmp/gethead.html");
	postUrl("/tmp/post.html");
}

4、安装libcurl库

①安装openssl库

1、wget https://www.openssl.org/source/openssl-1.1.1a.tar.gz        下载openssl库

openssl官网        当无法wget方式下载到openssl库时可到官网下载

2、tar xvf openssl-1.1.1s.tar.gz           解压openssl库

3、./config                                           按照默认配置,默认路径在/usr/local

4、make                                              编译

5、sudo make install                           安装                                  

②安装libcurl库

1、tar xvf curl-7.71.1.tar.bz2                解压curl库

2、./configure --prefix=$PWD/_install --host=arm-linux --with-ssl       配置文件

$PWD                代表获取当前路径

--host=arm-linux    代表交叉编译出来的文件可以运行在arm-linux系统上

--with-ssl        支持https协议

3、make                        编译

4、sudo make install              安装

5、export LD_LIBRARY_PATH=        将lib设置成环境变量

5、静态库,动态库的概念

①库的类型

1、静态函数库:程序在执行前就加入到目标程序中去了,相当于做了一份拷贝
优点:速度快,移植方便        缺点:体积大,更新、部署、发布麻烦

2、动态函数库:程序执行后再去动态的加载这个库
优点:体积小,程序更新迭代方便        缺点:速度慢,发布时需要提供依赖的动态库

②静态库的制作

1、gcc a.c -c               生成.o文件

2、ar rcs libtest.a a.o        生成.a文件(静态库)

③静态库的使用

我们做了一个libtest.a的静态库文件,我们编译时需要用到这个静态库

gcc b.c -ltest -L ./ 

-ltest        指定要用的静态库,库名砍头去尾

-L ./        告诉gcc编译器从-L指定的路径去找静态库,默认是去/usr/lib或/usr/local/lib路径去找

④动态库的制作(比较常用)

1、gcc -share -fpic test.c -o libtest.so

-share        指定生成动态库

-fpic           该选项作用于编译阶段,使用该选项,以生成位置无关的代码

⑤动态库的使用

1、我们做了一个libtest.so的动态库文件,我们编译时需要用到这个动态库

gcc b.c -ltest -L ./

-ltest        指定要用的动态库,库名砍头去尾

-L ./        告诉gcc编译器从-L指定的路径去找动态库,默认是去/usr/lib或/usr/local/lib路径去找

2、此时去运行可执行文件大概率是运行不起来的,因为程序在执行前在/usr/lib路径下找不到动态库

方法一:将动态库拷贝到/usr/lib路径下

方法二:export LD_LIBRARY_PATH=“动态库的路径”

此方法是临时的,临时将动态库的路径添加到系统寻找的路径,重新开个终端就用不了了,所以一般编写个shell脚本,在执行程序前添加一次环境变量

6、交叉编译

①概述

编译:        是在一个平台上生成该平台的可执行代码

交叉编译:是在一个平台上生成另一个平台的可执行代码

比如我们在window-keil软件上面编写C51代码并编译,但是代码是在C51单片机上面运行的

在VM虚拟机ubantu,x86/Linux架构上编写并编译香橙派ARM/Linux架构可执行的代码

gcc -v可以看当前编译器的版本信息等

②为什么要交叉编译

1、目标平台上的资源贫乏,无法运行我们需要的编译器,比如C51内存太小了

2、目标平台还没有建立,连操作系统都没有,操作系统也要交叉编译

③交叉编译工具安装

交叉编译器 tools-master

GitHub - raspberrypi/tools

1、unzip tools-master.zip        解压工具包

2、/home/CLC/PI/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gcc        树莓派香橙派的编译工具在该目录下

3、echo $PATH        可以查看当前环境变量

4、临时配置方式:export PATH=

5、永久配置方式:修改工作目录下的.bashrc隐藏文件

增加下面指令

export PATH=/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/FriendlyARM/toolschain/4.5.1/bin:/home/CLC/PI/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin

然后使用 source ./.bashrc指令重新加载配置文件

④交叉编译代码测试

1、file demo1.c        可以查看执行文件匹配的执行系统等信息

2、scp demo1.c pi@192.168.71.7:/home/pi        可以通过网络传输文件

3、grep gcc * -nir        这个指令可以查到路径底下关于gcc字符串相关的所有内容

WiringPi库做的不是很好,在编译的时候无法配置编译,导致在VM里编译出来的wiringPi库是X86架构的,此时只能从树莓派拿libwiringPi.so.2.50动态库拿来用

参考博文:树莓派在X86/Linux架构如何交叉编译

⑤软硬链接

软链接类似于window系统的创建快捷方式,不占空间,指向另一个文件

ln -sf 要被链接的文件 快捷方式        s是创建软链接 f是强制创建

硬链接则是拷贝了一份

ln 要被链接的文件 快捷方式

7、人脸识别代码实现

​​​​​​​

#include <stdio.h>
#include <curl/curl.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
size_t readData( void *ptr, size_t size, size_t nmemb, void *stream)
{
	char buf[1024]={'\0'};
	strncpy(buf,ptr,sizeof(buf));
	
	printf("-----------------------get data---------------------------\n");
	printf("%s\n",buf);
}



int getBase64(char *fileName,char **buf)
{
	int fd;
	int size;
	int n_read;
	char command[128];
	sprintf(command,"base64 %s >base64.txt",fileName);
	system(command);
	
	fd = open("base64.txt",O_RDWR);
	size = lseek(fd,0,SEEK_END);
	printf("size is %d\n",size);
	*buf =(char *)malloc(sizeof(char)*size+10);
	memset(*buf,'\0',sizeof(*buf));
	lseek(fd,0,SEEK_SET);
	n_read = read(fd,*buf,size);
	printf("n_read is %d\n",n_read);
	close(fd);
	return 0;
}


bool postUrl()
{
	CURL *curl;
	CURLcode res;
	int fd;
	int n_read;
	char *img1;
	char *img2;
	char *key="Pk7uVDnEr4UD2MF5AadPiU";
	char *secret="38a46c806bf643d7be40a07cc63b75c7";
	int typeid=21;
	char *format="xml";
	char *postString;
	getBase64("1.jpg",&img1);
	getBase64("2.jpg",&img2);	

	postString = (char *)malloc(strlen(img1)+strlen(img2)+1024);
	memset(postString,'\0',sizeof(postString));
	sprintf(postString,"&img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s",img1,img2,key,secret,typeid,format);
	curl = curl_easy_init();
	if (curl)
	{
		curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookie.txt"); // 指定cookie文件
		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postString);    // 指定post内容
		curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do");   // 指定url
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, readData);
		res = curl_easy_perform(curl);
		curl_easy_cleanup(curl);
	}
	return true;
}
int main(void)
{
	curl_global_init(CURL_GLOBAL_ALL);
	postUrl();
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值