首先很是感谢,上篇文章中一些前辈的指导,其中一些意见让我获益匪浅!html
关于物联网,我以为灵魂仍是在软件上,前端的各类硬件联网标准一旦造成也就没啥事了,更多的仍然是数据的存储,分析。其实,物联网说白了更是一种数据服务一条龙。从数据的采集到数据的传送以及数据的存储和处理。数据的传送就不用说了,属于通讯的范畴,属于宽带和三大运营商的领地,数据的的采集属嵌入式的范畴,数据的存储可能通常的程序员和DBA就能够搞定,最有核心的部分就是数据的分析了,只惋惜作数据挖掘和大数据处理的,大都是博士和硕士级别的吧!因此作为一名普通的二本毕业生,我准备将目标锁定在嵌入式的方向,准确的说是嵌入式软件开发工程师。前端
一直以来经常张口物联网,闭口智能家具,终于在最后的时间里,付出了实践,作了一个基于嵌入式Linux的智能家具远程控制系统,固然系统在不断的完善,目前已经实现了远程控制和环境信息实时上传的功能。但愿各路大牛,多拍板砖,多提指导性意见。java
本文的主要目标是展现系统的服务器,关于嵌入式环境搭建/驱动的编写,不详细说明。程序员
在实现智能家居控制系统以前,咱们须要搭建一我的机交互界面,这里我主要采用了HTML页面,也就是最终实现的目标是,人们能够在有网络的地方登录位于家里的嵌入式WEB服务器,而后经过这些网页来进行用电器的操控,同时,也能够将家里的实时环境值传送到HTML页面,你能够远程查看居室内的环境信息,远程为家人打开空气净化器或者是空调。web
STEP 0:开发准备面试
宿主机:Ubuntu操做系统ajax
开发板:FriendlyARM mini2440编程
驱动程序:LED驱动,温度传感器驱动浏览器
相关技术准备:Socket编程/HTTP协议/JavaScript服务器
STEP 1:实现WEB服务器
嵌入式虽然小,但仍是有一批开源的服务器是可供选择的,好比大名鼎鼎的boa,小巧强悍。我在最开始的时候也是选择移植boa服务器做为智能家具的服务器,可是后来在添加家具控制模块和温度传输模块的时候以为很不方便,因而呼就决定手动打造一个服务器,虽然和boa相差十万里,可是学到的东西也更多,并且对web的机理有了更深入的认识,觉的做为一个学习者,值了。
在徒手开发服务器以前,你必需要知道,web底层的工做机理,说到这里有一个段子,有一次我去面试,岗位是java web,boss问我你对web有什么认识,我随口一说:“其实web说到底就是socket和http”,后来在一次聚餐的时候boss给我说:“当听到一个还未毕业的学生对web能有如此认识,感到很意外,因此即便你没有经验我也仍是会雇佣的。”看来,有时候吹牛逼真的很管用,哈哈。
虽然是吹牛逼,但web的实质的确是socket和http协议,浏览器端我不清楚也就不乱说了,可是我擦浏览器里面必定有个socket来和咱们的服务器进行通讯。接下来详细说说咱们的服务器端,服务器要想和浏览器取得通讯,首先须要创建一个socket,而后就是传统的网络编程,可是要注意,服务器和浏览器进行“对话时”,使用的是“HTTP”语言。也就是说web的实质是HTML+SOCKET+浏览器。然而socket又是tcp/ip协议的程序实现层,所以web的实质就是html+TCP/IP+浏览器。然而HTML的实质又是文件,所以web的实质又是 文件+TCP/IP+浏览器(文件翻译器(特殊文件翻译器))。关于浏览器我是在研究的很少,不敢乱说。
所以,总结成一句话就是:“WEB就是向一台被称为服务器的计算机上请求文件,服务器将指定文件发送到浏览器,而后浏览器解析文件并展现的一个过程”。
server_sockfd=socket(AF_INET,SOCK_STREAM,0); if(server_sockfd<0) { printf("create socket failed!\n"); exit(EXIT_FAILURE); } memset(&server_addr,0,sizeof(server_addr)); server_addr.sin_family=AF_INET; server_addr.sin_port=htons(PORT); server_addr.sin_addr.s_addr=INADDR_ANY; if(bind(server_sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr))!=0){ printf("bind error!\n"); exit(EXIT_FAILURE); }
通过上面的操做,已经为服务器建立了一个socket,也为socket绑定ip地址和端口,这样一来,就为咱们的服务器在茫茫的网络海洋中有了准确的定位。
关于socket和sockaddr_in,我一直是这样理解的,一个socket至关于一部手机,若是你想别人可以打通你的手机,首先你要有一个SIM卡,而这个sockaddr_in则至关于sim卡,一旦和你手机绑定后,别人(客户端)就能够向你发起呼叫。
接下来就是socket编程的通常步骤,Listen和accpect,至关于你的手机装上了SIM卡而且打开了手机,等待别人的呼叫。
client_sockfd=accept(server_sockfd,(struct sockaddr*)&client_addr,&addr_len);
accpect函数实现阻塞程序的继续进行,直到有客户端发起请求,当有客户端发起请求的话,accpect函数返回这个连接的描述符号。返回的结果表明客户端与服务器的连接描述,下面能够直接用这个描述符来表明已经创建的连接关系。
进行到此时,比如一我的拨通了你的电话而且你接听了电话,此刻大家的连接创建了。你能够用耳朵贴在话筒上听那人说了些什么,在咱们的程序里你一样能够用recv来接听客户端都发送了那些请求。
int recv_len=recv(client_sockfd,buffer,sizeof(buffer),0);
其中,buffer表明接收到客户端请求信息以及该客户端的相关信息。仿佛那人给你说的那些话。
关于buffer会是什么内容,相信没有接触过的人都很好奇,我也同样,因而乎打印了出来(前提是我在浏览器地址栏输入了http:127.0.0.1:8000/main.html):
GET /main.html HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:34.0) Gecko/20100101 Firefox/34.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
接下来就发现了这些有意思的东西(不要笑我,我真的是小白),第一次看见这东西真的很惊奇。看到了这里我瞬间明白了不少东西:
1 若是我又一个服务器,我能知道,那些ip访问了个人服务器,访问了多少次,地理位置在哪里。
2 我知道了他用的什么浏览器
3 我知道了他的主机是什么系统,还有有关本次连接使用的语言/编码方式/连接类型。。。
其实,咱们最关心的就是第一句,第一句是它(客户端)想GET main.html;意思是浏览器想向服务器请求main.html。
好了,若是你想在浏览器成功展现出main.html,你须要将main.html整个文件发送给客户端,可是请注意第一句“GET /main.html HTTP/1.1”,有没有发现它们有着特殊的形式,这就是WEB的语言吧,暂且这样称呼它。若是咱们直接调用write函数将main.html发送给客户端,客户端会不会以为太迷茫,它会以为发了一坨什么东西,所以在这里服务器也要以相似的形式首先给浏览器发送一段相似的文字而后将整个main.html文件发送过去:
HTTP/1.1 200 OK\r\n
Conten-Type:html\r\n
发送main.html的完成代码以下:
1 sprintf(buffer,"HTTP/1.1 200 OK\r\n"\ 2 "Conten-Type:%s\r\n"\ 3 "\r\n",mine_type); 4 int file_length=strlen(buffer); 5 do{ 6 if(write(socket_fd,buffer,file_length)<0){ 7 close(fd); 8 break; 9 } 10 }while((file_length=read(fd,buffer,sizeof(buffer)))>0);
其中mine_type为文件的类型,好比jif,png,html等等。
至此,一个完整的会话就完成了,一个超级无敌简易的网页浏览器也就搞定了。
STEP2:智能家具控制模块
严格的说,这是web服务器的扩展模块,就是这个服务器不只可以提供网页的文件资源,还能够调用驱动来进行硬件的操做。
好比要进行灯光控制,在html页面里有一个灯泡的图片按钮,当点击按钮的时候,用JavaScript想后台发送制定的请求内容,好比发送请求内容为:“myled.cgi”,注意这里的后缀不表明请求一个cgi的文件,由于服务器是本身的写的本身解析的,想表明什么本身说了算,就tm这么任性和这么爽!这里我指定它表明灯光控制部分。
1 int recv_len=recv(client_sockfd,buffer,sizeof(buffer),0); 2 printf("*****%d bytes recved!***********\n",recv_len); 3 p_buffer=buffer; 4 if(0==strncmp("GET /myled.cgi",buffer,14)) 5 { 6 printf("hello,heat nan!\n"); 7 send_light_cmd(p_buffer,client_sockfd); 8 9 }
以上的代码,我首先判断它请求的操做是否为灯光操做,若是是则将这些信息做为参数传递给灯光模块处理。
关于灯光模块分为两个部分,一个部分是肯定对那个灯进行操做,第二个部分是执行硬件操做,若是是用电器的开关 ,则主要是设置与用电器绑定的IO口电平。
STEP3:实时环境信息模块
关于实时环境信息模块和智能家具控制模块一模一样,首先当用户进入环境信息界面,ajax主动向服务器每10s发送一次温度请求,服务器接受到指令后,立刻调用温度传感器驱动采集一次温度,而后将温度传递到前端的html页面,如此让用户每隔10ms看到家里的温度一次,也算实时吧!至此,一个家居远程控制系统就算完成了,不能叫系统吧!此时感受如此之小 ,叫个小demo吧!此时此刻,家里的电器确实是连上网了,应该能够叫作“物联网了吧!”若是将采集的温度值不断的和设定喜爱温度值做比较从而让程序自动控制空调和地暖的开关,这应该叫“智能家居了吧!”。然而,这应该是现实的物联网;理想的物联网应该是这样:你的空调会受到一个巨大的数据平台作支持,这个数据平台分别链接了最权威的健康机构,能够提供不一样时节/不一样时间段最健康的温度,你的空调会和你的手机相互通讯,手机会告诉空调,孩子主人距离家里10千米,请你立马工做。空调应当会有记忆功能,分别记住主人在不一样时段,不一样季节最喜好的温度,你的空调应当和你的手环相连,当你在左手跟着右手一个慢动做的时候,手环会向空调发出指令,孩子主人心跳加速,体温上升,速度降温,从而不会让你大汗淋漓。若是当这一天真的来临,请叫他真正的物联网时代吧!