安防监控实现之HTML框架分析
HTTP 方法:GET 对比 POST
什么是 HTTP ?
超文本传输协议(HTTP)的设计目的是保证客户端与服务器之间的通信。
HTTP 的工作方式是客户端与服务器之间的请求-应答协议。
web 浏览器可能是客户端,而计算机上的网络应用程序也可能作为服务器端。
举例:客户端(浏览器)向服务器提交 HTTP 请求;服务器向客户端返回响应。响应包含关于请求的状态信息以及可能被请求的内容。
两种 HTTP 请求方法:GET 和 POST
在客户机和服务器之间进行请求-响应时,两种最常被用到的方法是:GET 和 POST。
GET - 从指定的资源请求数据。
POST - 向指定的资源提交要被处理的数据。
键值对 key value 对应
键值对于键值对之间用&分割
GET 方法
请注意,查询字符串(名称/值对)是在 GET 请求的 URL 中发送的:
/test/demo_form.php?name1=value1&name2=value2
有关 GET 请求的其他一些注释:
GET 请求可被缓存
GET 请求保留在浏览器历史记录中
GET 请求可被收藏为书签
GET 请求不应在处理敏感数据时使用
GET 请求有长度限制
GET 请求只应当用于取回数据
POST 方法
请注意,查询字符串(名称/值对)是在 POST 请求的 HTTP 消息主体中发送的:
POST /test/demo_form.php HTTP/1.1
Host: w3cschool.cc
name1=value1&name2=value2
有关 POST 请求的其他一些注释:
POST 请求不会被缓存
POST 请求不会保留在浏览器历史记录中
POST 不能被收藏为书签
POST 请求对数据长度没有要求
比较 GET 与 POST
下面的表格比较了两种 HTTP 方法:GET 和 POST。
GET POST
后退按钮/刷新 无害 数据会被重新提交(浏览器应该告知用户数据会被重新提交)。
书签 可收藏为书签 不可收藏为书签
缓存 能被缓存 不能缓存
编码类型 application/x-www-form-urlencoded application/x-www-form-urlencoded or multipart/form-data。
为二进制数据使用多重编码。
历史 参数保留在浏览器历史中。 参数不会保存在浏览器历史中。
对数据长度的限制 是的。当发送数据时,GET 方法向 URL 添加数据;
URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。 无限制。
对数据类型的限制 只允许 ASCII 字符。 没有限制。 也允许二进制数据。
安全性 与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。
在发送密码或其他敏感信息时绝不要使用 GET !POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。
可见性 数据在 URL 中对所有人都是可见的。 数据不会显示在 URL 中。
其他 HTTP 请求方法
下面的表格列出了其他一些 HTTP 请求方法:
方法 描述
HEAD 与 GET 相同,但只返回 HTTP 报头,不返回文档主体。
PUT 上传指定的 URI 表示。
DELETE 删除指定资源。
OPTIONS 返回服务器支持的 HTTP 方法。
CONNECT 把请求连接转换到透明的 TCP/IP 通道。
/*用C语言模拟heml框架*/
#include<stdio.h>
int homework_for_you()
{
int sum = 0;
int i = 0;
for(i = 1;i <= 10; i++){
if(i % 5 == 0){
continue;
}
sum += i;
printf("i = %d\n",i);
}
printf("sum = %d\n",sum);
printf("well done!\n");
return 0;
}
int class_study()
{
int cls[3]={0};
int i = 0;
printf("example: level2 day4 class3 : 2 4 3 \n");
printf("please input your class: ");
do{
do {
scanf("%d",&cls[i++]);
}while(getchar() != '\n');
}while(i > 3);
printf("class begin, stand up ,please....\n");
homework_for_you();
return 0;
}
int embedded_development(int i)
{
printf("embedded_development.\n");
if(i == 1){
printf("welcome.");
class_study();
}else{
return i;
}
return 0;
}
int internet_development(int i)
{
printf("internet_development.\n");
return 0;
}
int starmaker_development(int i)
{
printf("starmaker_development.\n");
return 0;
}
int main(int argc, const char *argv[])
{
int data[3] = {0};
int i = 0;
printf("*****************************************\n");
printf("****1.Embedded 2.Internet 3.StarMaker****\n");
printf("*****************************************\n");
printf("please input the data: ");
scanf("%d",&i);
getchar();
switch (i){
case 1:
embedded_development(i);
break;
case 2:
internet_development(i);
break;
case 3:
starmaker_development(i);
break;
default:
printf("input error! \n");
break;
}
return 0;
}
可以花2-3天学习了解一下
学习网站: html css
网页->CGI->信号量->a9消息大致过程:
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>硬件控制 Control</title>
<style type="text/css">
.main {
float: none;
height: 424px;
width: 424px;
background-image: url();
background-repeat: no-repeat;
}
.strip {
height: 28px;
width: 200px;
margin-top: 55px;
margin-bottom: 30px;
margin-left: 100px;
}
.strip1 {
height: 28px;
width: auto;
float: inherit;
}
.strip2 {
height: 30px;
width: 275px;
margin-top: 30px;
margin-bottom: 30px;
margin-left: 100px;
}
.strip3 {
height: 60px;
width: 250px;
margin-top: 30px;
margin-bottom: 30px;
margin-left: 100px;
}
.clear {
clear: both;
height: 0;
font-size: 1px;
line-height: 0px;
}
.demo {
position: relative;
left: 360px;
top: 10px;
}
</style>
</head>
<body background="./images/huaqing00.jpg">
<table width="600" border="2" height="317" align="center" background="./images/fs4412.jpg">
<tr>
<td> </td>
</tr>
</table>
<table width="600" height="50" border="2" align="center">
<tr>
<td width="294">
<div align="center">硬件控制</div>
</td>
<td width="296">
<div align="center">
<a href="home1.html">回主页</a>
</div>
</td>
</tr>
</table>
<table width="400" height="270" align="center" border="3" bordercolor="red">
<td height="60">
<div align="center">
<form id="form1" name="form1" method="post" action="cgi-bin/a9_led.cgi">
<div class="strip1">
<input type="hidden" name="store" id="hiddenField" value="1" /> Led:
<label>
<input type="radio" name="led" value="1" id="led_0" />
on</label>
<label>
<input type="radio" name="led" value="0" id="led_1" />
off</label>
<input type="submit" name="button" id="button" value="确定" />
</div>
</form>
</div>
</td>
</tr>
<tr>
<td height="60">
<div align="center">
<form id="form4" name="form4" method="post" action="cgi-bin/a9_beep.cgi"> <input type="hidden" name="store" id="hiddenField" value="1" />
<label>Beep:
<input type="radio" name="beep" value="1" id="beep_0" />
开</label>
<label>
<input type="radio" name="beep" value="0" id="beep_1" />
关</label>
<input type="submit" name="button4" id="button4" value="提交" />
</form>
</div>
</td>
</tr>
<tr>
<td height="60">
<div align="center">
<form id="form3" name="form3" method="post" action="cgi-bin/a9_seg.cgi">
<div class="strip1"> <input type="hidden" name="store" id="hiddenField" value="1" />
<label>Seg:
<input type="radio" name="seg" value="1" id="seg_0" />
on</label>
<label>
<input type="radio" name="seg" value="0" id="seg_1" />
off</label>
<input type="text" name="segvalue" id="textfield" size="2" />
<input type="submit" name="button3" id="button3" value="提交" />
</div>
</form>
</div>
</td>
</tr>
<tr>
<td height="60">
<div align="center">
<form id="form2" name="form2" method="post" action="cgi-bin/zigbee_fan.cgi">
<div class="strip1"> <input type="hidden" name="store" id="hiddenField" value="1" /> Fan:
<label>
<input type="radio" name="fan" value="0" id="fan_0" />
off</label>
<label>
<input type="radio" name="fan" value="1" id="fan_1" />
1</label>
<label>
<input type="radio" name="fan" value="2" id="fan_2" />
2</label>
<label>
<input type="radio" name="fan" value="3" id="fan_3" />
3</label>
<input type="submit" name="button2" id="button2" value="确定" />
</div>
</form>
</div>
</td>
</tr>
</table>
<tr>
<td>
<form>
<div class="demo" align="left">我国安防行业在经过了近30年的发展后,已经形成了长三角、珠三角、环渤海三大产业聚集区,<br/>
并且诞生了以海康威视、大华股份、宇视科技为首的第一阵营,前三强市场份额加起来占比达到50%以上,<br/>
产业集成度较高。每个月光是从杭州生产出来的安防摄像机都高达百万台,市场竞争激烈。
<br/>
<br/>
</form>
</div>
</td>
</tr>
</body>
</html>
cgi
#include <stdio.h>
#include "cgic.h"
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define N 8
struct msg
{
long type;
long msgtype;
unsigned char text[N];
};
int cgiMain()
{
key_t key;
char buf[N];
char sto_no[2];
int msgid;
struct msg msg_buf;
memset(&msg_buf, 0, sizeof(msg_buf));
/*"cgiFormString" 是一个函数,通常用于处理 CGI(通用网关接口)编程中的表单数据。
当用户通过 HTTP POST 或 GET 请求提交表单数据时,这些数据会传递给服务器端的 CGI 脚本。在 CGI 程序中,可以使用 "cgiFormString" 函数来获取特定表单字段的值。*/
cgiFormString("beep", buf, N);
cgiFormString("store", sto_no, 2);
if ((key = ftok("/tmp", 'g')) < 0)
{
perror("ftok");
exit(1);
}
//msgget 函数是用来创建或打开一个消息队列的函数。它接受两个参数,一个是 key,用于标识消息队列的唯一标识符,另一个是 flags,用于设置消息队列的创建或打开方式
if ((msgid = msgget(key, 0666)) < 0)
{
perror("msgget");
exit(1);
}
/*
if (buf[0] == '1')
{
msg_buf.text[0] = ((sto_no[0] - 48)) << 6 | (1 << 4) | (1 << 0);
}
else
{
msg_buf.text[0] = ((sto_no[0] - 48)) << 6 | (1 << 4) | (0 << 0);
}
*/
switch (buf[0])
{
case '0':
{
msg_buf.text[0] = ((sto_no[0] - 48)) << 6 | (1 << 4) | (0 << 0);//从网页获取到的是字符,表达式 (sto_no[0] - 48) 的含义是将字符串 sto_no 中的第一个字符转为 ASCII 码并减去 48。由于 ASCII 码中数字字符的起始值是 48,所以这个表达式的结果是将字符串的第一个字符转为数字的值。
break;
}
case '1':
{
msg_buf.text[0] = ((sto_no[0] - 48)) << 6 | (1 << 4) | (1 << 0);
break;
}
case '2':
{
msg_buf.text[0] = ((sto_no[0] - 48)) << 6 | (1 << 4) | (2 << 0);
break;
}
case '3':
{
msg_buf.text[0] = ((sto_no[0] - 48)) << 6 | (1 << 4) | (3 << 0);
break;
}
}
//判读消息类型
msg_buf.type = 1L;//1L代表home1
msg_buf.msgtype = 2L;//2L代表蜂鸣器
//通过队列将msg_buf数据发送出去,msgsnd 函数的作用是向指定的消息队列发送消息。它接受四个参数:消息队列的标识符 msqid、指向要发送的消息结构体的指针 msgp、消息的长度和消息的类型。
//发送消息时,操作系统会将消息复制到消息队列中,并根据消息的类型进行排序。其他进程或线程可以通过调用 msgrcv 函数从消息队列中接收消息。
//总结来说,msgsnd 函数的作用是将消息发送到指定的消息队列中,供其他进程或线程接收。消息队列的标识符通过 msgget 函数获得,而接收消息的进程或线程通过 msgrcv 函数来接收。
msgsnd(msgid, &msg_buf, sizeof(msg_buf) - sizeof(long), 0);
sto_no[0] -= 48;
cgiHeaderContentType("text/html\n\n");
fprintf(cgiOut, "<HTML><HEAD>\n");
fprintf(cgiOut, "<TITLE>My CGI</TITLE></HEAD>\n");
fprintf(cgiOut, "<BODY>");
fprintf(cgiOut, "<H2>send sucess</H2>");
//fprintf(cgiOut, "<a href='.html'>返回</a>");
fprintf(cgiOut, "<meta http-equiv=\"refresh\" content=\"1;url=../a9_zigbee%d.html\">", sto_no[0]);
fprintf(cgiOut, "</BODY>\n");
fprintf(cgiOut, "</HTML>\n");
return 0;
}
a9客户端
#include "data_global.h"
extern int msgid;
extern key_t key;
extern pthread_mutex_t mutex_client_request,
mutex_refresh,
mutex_sqlite,
mutex_transfer,
mutex_analysis,
mutex_sms,
mutex_buzzer,
mutex_led,
mutex_camera;
extern pthread_cond_t cond_client_request,
cond_refresh,
cond_sqlite,
cond_transfer,
cond_analysis,
cond_sms,
cond_buzzer,
cond_led,
cond_camera;
extern char recive_phone[12] ;
extern char center_phone[12] ;
struct msg msgbuf;
void *pthread_client_request(void *arg)
{
if((key = ftok("/tmp",'g')) < 0){
perror("ftok failed .\n");
exit(-1);
}
msgid = msgget(key,IPC_CREAT|IPC_EXCL|0666);
if(msgid == -1) {
if(errno == EEXIST){
msgid = msgget(key,0777);
}else{
perror("fail to msgget");
exit(1);
}
}
printf("pthread_client_request\n");
while(1){
bzero(&msgbuf,sizeof(msgbuf));
printf("wait form client request...\n");
msgrcv (msgid, &msgbuf, sizeof (msgbuf) - sizeof (long), 1L, 0);
printf ("Get %ldL msg\n", msgbuf.msgtype);
printf ("text[0] = %#x\n", msgbuf.text[0]);
switch(msgbuf.msgtype){
case 1L:
printf("hello led\n");
break;
case 2L:
printf("hello beep\n");
break;
case 3L:
printf("hello seg\n");
break;
case 4L:
printf("hello fan\n");
break;
case 5L:
printf("set env data\n");
printf("temMAX: %d\n",*((int *)&msgbuf.text[1]));
printf("temMIN: %d\n",*((int *)&msgbuf.text[5]));
printf("humMAX: %d\n",*((int *)&msgbuf.text[9]));
printf("humMAX: %d\n",*((int *)&msgbuf.text[13]));
printf("illMAX: %d\n",*((int *)&msgbuf.text[17]));
printf("illMAX: %d\n",*((int *)&msgbuf.text[21]));
break;
case 6L:
case 7L:
case 8L:
case 9L:
printf("你可以将这些作为扩展来学习,加油.\n");
break;
case 10L:
{
int i = 0 , j = 0 ;
for(i = 0 ; i < 11; i++){
recive_phone[i] = msgbuf.text[i];
}
recive_phone[i] = '\0';
printf("recive:%s\n",recive_phone);
for(j = 0 ;msgbuf.text[i] != '\0' && j < 12; i++, j++)
{
center_phone[j] = msgbuf.text[i];
}
center_phone[j] = '\0';
printf("center:%s\n",center_phone);
#if 0
pthread_mutex_lock (&mutex_slinklist);
sqlite_InsertLinknode (ENV_UPDATE, all_info_RT, sto_no, 0);//0,0鍒嗗埆鏄�浠撳簱鍙峰拰璐х墿绉嶇被鍙�
pthread_mutex_unlock (&mutex_slinklist);
pthread_cond_signal (&cond_sqlite);
#endif
}
break;
default:
break;
}
}
}
#if 0
long msgtype;//具体的消息类型
消息类型的分配:
1L: LED控制
2L: 蜂鸣器控制
3L: 四路LED灯模拟的数码管
4L: 风扇
5L: 温湿度最值设置
6L-7L-8L-9L,用于个人的扩展
10L: 3G通信模块-GPRS
switch(msgbuf.msgtype){
case 1L: ... break;
....
default .... break;
}
#endif