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
设置重定位URLCURLOPT_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 "); // 指定urlcurl_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"); // 指定urlcurl_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();
}
Linux智能家居项目相关推荐
- 智能家居项目开发: 设计模式(工厂模式)+ 线程池 + Socket (持续更新中)
智能家居项目开发 一.智能家居功能细节拆分 控制区: 外设区: 面向对象类和对象的概念 结构体新玩法 二.工厂模式 1. 工厂模式的概念 2. 工厂模式的实现 3. 工厂模式使用及功能验证 三.智能家 ...
- 基于stm32的智能家居项目
基于stm32的智能家居 具体教程可以看文中的B站链接,上面有手把手教程 本人其他项目链接基于linux的智能仓储项目 基于Qt的人脸识别 移植人脸识别到Linux开发板上 基于正点原子的IMX6UL ...
- 视频教程-5G物联网云平台智能家居项目30天搞定-物联网技术
5G物联网云平台智能家居项目30天搞定 我叫连志安,现任职广东长虹技术研究所(国企).之前在康佳集团(国企).CVTE(上市公司)等公司任职.负责过Android TV.智能网关.路由器.智能家居.安 ...
- 智能家居 (8) ——智能家居项目整合(网络控制线程、语音控制线程,火灾报警线程)
目录 mainPro.c(主函数) 指令工厂 inputCommand.h voiceControl.c(语音控制) socketControl.c(网络线程) 控制工厂 contrlEquipmen ...
- 物联网智能家居项目---智能卧室
智能卧室 介绍 设计需求 功能介绍 准备 软件准备 硬件准备 项目制作 库文件调用和变量定义 超声波测距函数 初始化 变量赋值和LCD显示屏显示温湿度 功能实现 后续 介绍 设计需求 为了提高用户生活 ...
- android 智能家居 pdf,智能家居项目化教程.pdf
作 者 :曾文波,伦硕波,黄日胜,钟建坤编著 出版发行 : 北京:中国水利水电出版社 , 2019.03 ISBN号 :978-7-5170-6858-7 页 数 : 151 原书定价 : 27.00 ...
- 树莓派智能家居项目整合(包含语音、socket、火灾、摄像头线程)
树莓派智能家居项目一 1.百度网盘下载代码链接 2.main.c 3.段错误 4.C语言的函数声明 4.1没声明的报错内容 5.关于报错,调试程序 坎坎坷坷,墨墨迹迹了这么久也算是完成了四个线程的同时 ...
- 智能家居项目(八)之树莓派+摄像头进行人脸识别
目录 1.编辑Camera.c 2.编辑contrlDevices.h 3.编辑mainPro.c 4.进行编译: 5.运行结果: ./test1 6.项目图片演示 智能家居项目(七)之Libcurl ...
- 嵌入式智能家居项目视频监控_智能化您的视频嵌入
嵌入式智能家居项目视频监控 Video content is taking over the Internet. The trend began long ago and the most recen ...
最新文章
- 主元素问题 Majority Element
- python方法重写_python 怎样实现重写
- spark任务jvm内存溢出
- 你必须要懂的APK瘦身知识
- Android之多线程----异步消息处理机制之Handler详解
- android peopleactivity.java,Android面试基础篇---Activity(上)
- 王者荣耀交流协会 — Alpha阶段中间产物
- 关于使用NLPIR-ICTCLAS分词系统
- Twaver-HTML5基础学习(38)劈分面板SplitPane
- 郑轻oj1000-从今天开始入坑C语言
- docker ss-pannel_docker+traefik配置mysql + panel
- 强化学习笔记: Model-based Approaches(2)
- oracle 18c 转 11g,安装Oracle:Oracle 18c、Oracle 11g
- 个别化教育计划IEP模板
- 安卓开发笔记(十一)—— 方向传感器,实现摇一摇动画音效,GPS定位
- 杭漂十年!我从「租客」到「房东」
- C语言中除以怎么使用
- noip2014:螺旋矩阵_网页设计:2014年值得关注的20个最热门趋势
- 数据可视化分析之热门旅游景区数据分析
- 从零开始学Java【JavaSE入门】