一、项目目标和框图
项目目标:实现通过网页控制信息采集和通过网页控制灯泡和蜂鸣器的亮灭
二、项目分析
1.服务器源码分析
- 初始化服务器
- 循环等待连接,连接后创建线程,调用线程函数msg_request,在函数中调用handler_msg函数分析请求
- 在handler_msg函数中,先查看请求协议内容,其次获取请求方法、URL、参数,判断请求方法,对need_handler赋值,确定请求资源路径,如果请求地址没有携带任何资源,则默认返回index.html文件,如果资源不存在,返回404,如果需要处理(get带参数、post)调用handle_request函数,如果不需要(get请求不带参数且资源存在),调用echo_www函数,直接返回资源
- handle_request函数主要获取post数据,调用parse_and_process函数处理正文内容
2. 结合Modbus部分整体流程分析
三、核心功能代码
1.采集传感器数据
modbus采集程序和webserver共同建立共享内存,modbus读取传感器得到的数据,将数据写入共享内存中;webserver将数据从共享内存中读出;
//modbus采集传感器
void *handler_thread(void *arg)
{
key_t key;
int shmid;
struct msp *p;
//创建key值
key = ftok("1.txt", 'x');
if (key < 0)
{
perror("ftok err");
return NULL;
}
printf("key: %#x
", key);
//创建或打开共享内存
shmid = shmget(key, 128, IPC_CREAT | IPC_EXCL | 0666); //没有则创建共享内存,已有则返回-1
if (shmid ctx, 0, 4, p->dest);
printf("%d %d %d %d
", p->dest[0], p->dest[1], p->dest[2], p->dest[3]);
//让从线程不退出,进程状态l也就是多线程
sleep(2);
}
return NULL;
}
//webserver服务器
static int handler_get(int sock, const char *input)
{
key_t key;
int shmid;
struct msp *p;
//创建key值
key = ftok("1.txt", 'x');
if (key < 0)
{
perror("ftok err");
return -1;
}
printf("key: %#x
", key);
//创建或打开共享内存
shmid = shmget(key, 128, IPC_CREAT | IPC_EXCL | 0666); //没有则创建共享内存,已有则返回-1
if (shmid dest[0], p->dest[1], p->dest[2], p->dest[3]);
printf("g:%d X:%dY:%dZ:%d
", p->dest[0], p->dest[1], p->dest[2], p->dest[3]);
char reply_buf[HTML_SIZE] = {0};
printf("handler_get
");
printf("%d %d%d%d
", p->dest[0], p->dest[1], p->dest[2], p->dest[3]);
sprintf(reply_buf, "%d %d %d %d", p->dest[0], p->dest[1], p->dest[2], p->dest[3]);
printf("resp = %s
", reply_buf);
send(sock, reply_buf, strlen(reply_buf), 0);
return 0;
}
2.控制灯泡和蜂鸣器
网页发出控制命令给webserver服务器控制灯和蜂鸣器的信息,webserver和modbus采集器用相同的条件建立两个程序间的消息队列,建立通信,将控制灯泡和蜂鸣器的信息传递给modbus采集器,modbus采集器用相关信息控制灯泡和蜂鸣器的开关
//modbus采集器
void *handler_thread2(void *arg)
{
key_t key;
int msgid;
key = ftok(".", 9);
if (key < 0)
{
perror("ftok err");
return NULL;
}
printf("key:%#x
", key);
//打开消息队列
msgid = msgget(key, IPC_CREAT | IPC_EXCL | 0666);
if (msgid ctx2, m.num, m.num2);
// modbus_write_bit(msg->ctx2, 1, dest[1]);
}
// //让从线程不退出,进程状态l也就是多线程
return NULL;
}
//webserver服务器
static int handler_set(int sock, const char *input)
{
key_t key;
int msgid;
key = ftok(".", 9);
if (key < 0)
{
perror("ftok err");
return -1;
}
printf("key:%#x
", key);
//打开消息队列
msgid = msgget(key, IPC_CREAT | IPC_EXCL | 0666);
if (msgid <= 0)
{
if (errno == EEXIST)
msgid = msgget(key, 0666);
else
{
perror("msgget err");
return -1;
}
}
printf("msgid: %d
", msgid);
int number1,number2;
//input必须是"data1=1data2=6"类似的格式,注意前端过来的字符串会有双引号
sscanf(input, "set=%dset2=%d", &number1,&number2);
printf("num1 = %d,num2=%d
", number1,number2);
char reply_buf[HTML_SIZE] = {0};
struct msgbuf mng;
mng.type = 10;
mng.num = number1;
mng.num2 =number2;
mng.ch = 'a';
msgsnd(msgid, &mng, sizeof(mng) - sizeof(long), 0); //0:阻塞,发完消息才返回
printf("num = %d num=%d
", number1 ,number2);
sprintf(reply_buf, "set=%dset2=%d", number1,number2);
printf("resp = %s
", reply_buf);
send(sock, reply_buf, strlen(reply_buf), 0);
return 0;
}
3.http网页显示和控制
将虚拟机的IP地址在网页中打开,然后查询传感器得到的数据和控制灯泡和蜂鸣器
信息采集
what 阿尔 donging 呢?
yes,我吃饭嘞
NO,我 dont eat
HTML(英文Hyper Text Markup Language的缩写)中文译为“超文本标记语言”。是用来描述网页的一种语言。
所谓超文本,因为它可以加入图片、声音、动画、多媒体等内容,不仅如此,它还可以从一个文件跳转到另一个文件,与世界各地主机的文件连接。
HTML 不是一种编程语言,而是一种标记语言 (markup language)
Web 浏览器的作用是读取 HTML 文档,并以网页的形式显示出它们。浏览器不会显示 HTML 标签,而是使用标签来解释页面的内容
用户名:
设备控制
LED灯
on:
off:
蜂鸣器
on:
off: