嵌入式web服务器BOA+CGI+HTML+MySQL项目实战——Linux
准备环境
操作系统: Ubuntu12.04 LTS
环境搭建: 需要 BOA,Apache,CCGI,MySQL,GCC
[Linux下嵌入式Web服务器BOA和CGI编程开发]
[数据库的相关知识——学习笔记] 的三
[mysql中文乱码问题解决 / C程序插入仍是乱码解决 / 卸载重装教学]
扩展: 我还用了[bootstrap]框架,CSS/JS
源码链接:GitHub:[传送门] , 码云:[传送门]
使用方法
环境准备好后,我们在 /var/www 下写HTML文件
在 /var/www/cgi-bin 下写c文件,编译后命名为.cgi。
编译命令仅供参考
gcc -o login.cgi login.c cgic.c -lpthread -ldl -lmysqlclient
程序都写好后,我们开始测试。
1、开启MySQL服务 默认开启
我的程序需要事先 新建用户test,数据库register,表user
mysql -utest -ptest
// 创建新用户test
mysql> create user 'test'@'localhost' identified by 'test';
// 给test用户所有权限
mysql> grant all privileges on *.* to test@localhost identified by 'test';
// 刷新权限
mysql> flush privileges;
mysql> create database register;
mysql> use register;
mysql> CREATE TABLE user(username varchar(20) PRIMARY KEY,password varchar(20));
2、开启BOA服务器,在/boa/src目录下
sudo ./boa
3、打开浏览器,访问localhost:端口号 访问的即 /var/www 目录
我直接访问 http://localhost:886/login.html 我的登录页面
其他页面都是同理。
思路讲解
开启boa服务器后,我们访问到我们在 /var/www 下编写的HTML文件,显示我们的登录页面。
我们点击“注册”按钮,跳转到 register.html
点击“注册”按钮,提交form表单信息给cgi-bin/register.cgi
cgi程序通过 cgiFormString函数试图检索发送给指定字段的字符串。存入变量中。我们连接MySQL数据库
将数据写入register数据库中的user表中(此数据库和表需要先建好)
处理完毕后,跳回 login.html 登录页面
现在我们输入数据,点击“登录”,同理将表单发给 login.cgi ,对数据在MySQL数据库中查询后,成功就来到base_config.html 配置页面。
然后我们输入相应数据,点击“提交”,交给base_config.cgi处理,之后任意发挥就好了。
我是打印出来,写入系统文件的代码暂时注释了,慎用
↑↑↑↑↑遇到问题可以参考页首的链接↑↑↑↑↑
相关源码
login.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>register</title>
<script src="js/jquery-2.2.3.min.js"></script>
<script src="js/jquery-ui.min.js"></script>
<link type="text/css" href="css/jquery-ui.min.css" rel="stylesheet">
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/bootstrap.min.js"></script>
<link type="text/css" href="css/login.css" rel="stylesheet">
<script src="js/my.js"></script>
<SCRIPT language = "JavaScript">
function checkUserName(){ //验证用户名
var fname = document.myform.username.value;
var reg=/^[0-9a-zA-Z]/;
if(fname.length != 0){
for(i=0;i<fname.length;i++){
if(!reg.test(fname)){
alert("只能输入字母或数字");
return false;}
}
if(fname.length<4||fname.length>16){
alert("只能输入4-16个字符")
return false;
}
}
else{ alert("请输入用户名");
document.myform.username.focus();
return false }
return true;
} function passCheck(){ //验证密码
var userpass = document.myform.password.value;
if(userpass == ""){
alert("未输入密码 \n" + "请输入密码");
document.myform.password.focus();
return false; }
if(userpass.length < 6||userpass.length>12){
alert("密码必须在 6-12 个字符。\n");
return false; }
return true; } function passCheck2(){
var p1=document.myform.password.value;
var p2=document.myform.password2.value;
if(p1!=p2){
alert("确认密码与密码输入不一致");
return false;
}else{
return true;
}
} function checkEmail(){
var Email = document.getElementById("email").value;
var e = Email.indexOf("@"&&".");
if(Email.length!=0){
if(e>0){
if(Email.charAt(0)=="@"&&"."){
alert("符号@和符号.不能再邮件地址第一位");
return false;
}
else{
return true;
}
}
else{
alert("电子邮件格式不正确\n"+"必须包含@符号和.符号!");
return false;
}
}
else{
alert("请输入电子邮件!")
return false;
}
} function checkbirthday(){ //验证用户名
var year = document.myform.birthday.value;
if(year < 1949 || year > 2007){
alert("年份范围从1949-2007年");
return false;}
return true; } function validateform(){
if(checkUserName()&&passCheck( )&&passCheck2()&&checkEmail()&&checkbirthday())
return true;
else
return false;
} function clearText( ) {
document.myform.user.value="" ;
document.myform.password.value="" ;
} //显示隐藏对应的switchPwd()方法:
$(function(){
// 通过jqurey修改
$("#passwordeye").click(function(){
let type = $("#password").attr('type')
if(type === "password"){
$("#password").attr("type","text");
}else{
$("#password").attr("type","password");
}
});
}); </SCRIPT>
</head>
<body>
<img src="img/login_bg.jpg" class="bg">
<div id="head">
<img src="img/login_head.png" width=100% height=auto />
</div>
<div id="center">
<form name="myform" onSubmit="return validateform( )" enctype="multipart/form-data" action="cgi-bin/login.cgi" method="post" >
<div class="input-group">
<h3>用户名:</h3> <input class="form-control" id="username" name="username" type="text" style="height:40px" value="" placeholder="只能输入字母或数字,4-16个字符"/>
</div>
<div class="input-group">
<h3>密 码:</h3> <input class="form-control" id="password" name="password" type="password" style="height:40px" value="" placeholder="密码长度6-12位"/>
<span class="input-group-btn">
<INPUT class="btn btn-default" id="passwordeye" type="button" value="show/hide"">
</span>
</div> <div id="btn">
<INPUT class="btn btn-primary" name="loginButton" type="submit" id="Button" value="登录" onclick="checkUserName()">
<a href="register.html"><INPUT class="btn btn-primary" name="registerButton" id="Button" type="button" value="注册"></a>
</div>
</form>
</div>
<div id="bottom">
<div class="footer" style="color:white;">
Copyright © 2013-2019 All Rights Reserved. 备案号:
</div>
</div>
</body>
</html>
对应 login.c
register.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>register</title>
<script src="js/jquery-2.2.3.min.js"></script>
<script src="js/jquery-ui.min.js"></script>
<link type="text/css" href="css/jquery-ui.min.css" rel="stylesheet">
<link type="text/css" href="css/register.css" rel="stylesheet">
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/bootstrap.min.js"></script>
<script src="js/my.js"></script>
<SCRIPT language = "JavaScript">
function checkUserName(){ //验证用户名
var fname = document.myform.username.value;
var reg=/^[0-9a-zA-Z]/;
if(fname.length != 0){
for(i=0;i<fname.length;i++){
if(!reg.test(fname)){
alert("只能输入字母或数字");
return false;}
}
if(fname.length<4||fname.length>16){
alert("只能输入4-16个字符")
return false;
}
}
else{ alert("请输入用户名");
document.myform.username.focus();
return false }
return true;
} function passCheck(){ //验证密码
var userpass = document.myform.password.value;
if(userpass == ""){
alert("未输入密码 \n" + "请输入密码");
document.myform.password.focus();
return false; }
if(userpass.length < 6||userpass.length>12){
alert("密码必须在 6-12 个字符。\n");
return false; }
return true; } function passCheck2(){
var p1=document.myform.password.value;
var p2=document.myform.password2.value;
if(p1!=p2){
alert("确认密码与密码输入不一致");
return false;
}else{
return true;
}
} function checkEmail(){
var Email = document.getElementById("email").value;
var e = Email.indexOf("@"&&".");
if(Email.length!=0){
if(e>0){
if(Email.charAt(0)=="@"&&"."){
alert("符号@和符号.不能再邮件地址第一位");
return false;
}
else{
return true;
}
}
else{
alert("电子邮件格式不正确\n"+"必须包含@符号和.符号!");
return false;
}
}
else{
alert("请输入电子邮件!")
return false;
}
} function checkbirthday(){ //验证用户名
var year = document.myform.birthday.value;
if(year < 1949 || year > 2007){
alert("年份范围从1949-2007年");
return false;}
return true; } function validateform(){
if(checkUserName()&&passCheck( )&&passCheck2()&&checkEmail()&&checkbirthday())
return true;
else
return false;
} function clearText( ) {
document.myform.user.value="" ;
document.myform.password.value="" ;
} //显示隐藏对应的switchPwd()方法:
$(function(){
// 通过jqurey修改
$("#passwordeye").click(function(){
let type = $("#password").attr('type')
if(type === "password"){
$("#password").attr("type","text");
}else{
$("#password").attr("type","password");
}
});
$("#passwordeye2").click(function(){
let type = $("#password2").attr('type')
if(type === "password"){
$("#password2").attr("type","text");
}else{
$("#password2").attr("type","password");
}
});
}); </SCRIPT>
</head>
<body>
<img src="img/login_bg.jpg" class="bg">
<div id="head">
<img src="img/register_head.png" width=100% height=auto />
</div>
<div id="center">
<form name="myform" onSubmit="return validateform( )" enctype="multipart/form-data" action="cgi-bin/register.cgi" method="post" >
<div class="input-group">
<h3>用 户 名:</h3><input class="form-control" id="username" name="username" type="text" style="height:40px" value="" placeholder="只能输入字母或数字,4-16个字符"/>
</div>
<div class="input-group">
<h3>密 码:</h3><input class="form-control" id="password" name="password" type="password" style="height:40px" value="" placeholder="密码长度6-12位"/>
<span class="input-group-btn">
<INPUT class="btn btn-default" id="passwordeye" type="button" value="show/hide"">
</span>
</div>
<div class="input-group">
<h3>确认密码:</h3><input class="form-control" id="password2" name="password2" type="password" style="height:40px" value=""/>
<span class="input-group-btn">
<INPUT class="btn btn-default" id="passwordeye2" type="button" value="show/hide"">
</span>
</div>
<div id="btn">
<INPUT name="registerButton" class="btn btn-primary" type="submit" id="Button" value="注册" onclick="checkUserName()">
<a href="login.html"><INPUT class="btn btn-primary" name="loginButton" id="Button" type="button" value="登录"></a>
</div>
</form>
</div>
<div id="bottom">
<div class="footer" style="color:white;">
Copyright © 2013-2019 All Rights Reserved. 备案号:
</div>
</div>
</body>
</html>
对应的 register.c
#include <stdio.h>
#include "cgic.h"
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <mysql/mysql.h>
#include <stdbool.h> #define SQL_SIZE 256 int cgiMain(void)
{
char username[];
char password[];
char email[];
//回显信息到HTML网页cgiHeaderContentType("text/html");
printf("<html>\n\n");
printf("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n\n");
printf("<p>\n\n"); if(cgiFormString("username", username, sizeof(username)) != cgiFormSuccess)
{
fprintf(stderr, "cgiFormString function username failed");
//exit(-1);
}
printf("用户名:%s\n\n",username);
printf("<br>\n\n");
// password gateway server_ip dns subnet_mask dhcp error
if(cgiFormString("password", password, sizeof(password)) != cgiFormSuccess)
{
fprintf(stderr, "cgiFormString function password failed");
//exit(-1);
}
printf("密码:%s\n\n",password);
printf("<br>\n\n");
/*
if(cgiFormString("email", email, sizeof(email)) != cgiFormSuccess)
{
fprintf(stderr, "cgiFormString function email failed");
//exit(-1);
}
printf("电子邮箱:%s\n\n",phone);
printf("<br>\n\n");
*/ /*** 将用户信息写入MySQL数据库中 ***/
//数据存储到数据库
MYSQL* conn;
bool isAutoCommit; // 初始化 MySQL
conn = mysql_init(NULL);
if(NULL == conn)
{
printf("errno:%d error:%s\n",mysql_errno(conn),mysql_error(conn));
exit(-);
} char ip[] = "127.0.0.1";
char user[] = "test";
char passwd[] = "test";
char database[] = "register";
int port = ; // 尝试与运行在主机上的MySQL数据库引擎建立连接
if(NULL == mysql_real_connect(conn,ip,user,passwd,database,port,NULL,))
{
printf("---errno:%d error:%s\n\n",mysql_errno(conn),mysql_error(conn));
exit(-);
} isAutoCommit = true;
// 根据mysql的autocommit参数设置来决定是否自动提交
mysql_autocommit(conn,isAutoCommit); // 设定数据库编码
mysql_query(conn,"SET NAMES 'utf8'");
mysql_query(conn,"SET CHARACTER SET utf8");
mysql_query(conn,"SET CHARACTER_SET_RESULT = utf8"); char cmd[SQL_SIZE];
// 置字节字符串cmd的前SQL_SIZE个字节为零且包括‘\0’
bzero(cmd, SQL_SIZE);
// 创建user表
// strcpy(cmd, "CREATE TABLE user(username varchar(20) PRIMARY KEY,password varchar(20));"); // 将sql语句写入cmd变量
sprintf(cmd, "INSERT INTO user values('%s', '%s');",username,password); printf("%s\n\n",cmd); // 向与指定的连接标识符关联的服务器中的当前活动数据库发送一条查询
if(mysql_query(conn,cmd) != )
{
printf("errno:%d error:%s\n\n",mysql_errno(conn),mysql_error(conn));
printf("<p>注册失败,请重新注册</p>\n\n");
sleep();
printf("<meta http-equiv=Refresh content=1;URL=../register.html>\n");
}
//mysql_affected_rows(conn); printf("<p>注册成功</p>\n\n");
printf("<br>\n\n");
printf("<p>您的用户名和密码为:</p>\n\n"); sprintf(cmd,"select * from user;"); MYSQL_RES *res;
MYSQL_ROW row; if(mysql_query(conn,cmd) != )
{
printf("errno:%d error:%s\n",mysql_errno(conn),mysql_error(conn));
return -;
} int num_fields = mysql_field_count(conn);
if(num_fields == )
{
printf("errno:%d error:%s\n",mysql_errno(conn),mysql_error(conn));
return -;
} res = mysql_store_result(conn);
if(NULL == res)
{
printf("errno:%d error:%s\n",mysql_errno(conn),mysql_error(conn));
return -;
} printf("<br>\n\n");
printf("<br>\n\n");
while((row = mysql_fetch_row(res)))
{
char arr[];
int i = ;
for( ; i<num_fields; i++)
{
printf("%s ",row[i]);
}
printf("\n\n");
printf("<br>\n\n");
} mysql_free_result(res); sleep(); printf("<meta http-equiv=Refresh content=1;URL=../login.html>\n"); return ;
}
嵌入式web服务器BOA+CGI+HTML+MySQL项目实战——Linux的更多相关文章
- 嵌入式web服务器BOA的移植及应用
嵌入式web服务器子系统 一.嵌入式web服务器的控制流程 如下图所示,嵌入式web服务器可实现通过网络远程控制嵌入式开发板,便捷实用. 控制流程:浏览器 --->>>嵌入式开发板 ...
- Linux下嵌入式Web服务器BOA和CGI编程开发
**目录**一.环境搭建二.相关配置(部分)三.调试运行四.测试源码参考五.常见错误六.扩展(CCGI,SQLite) # 一.环境搭建操作系统:Ubuntu12.04 LTSboa下载地址(但是我找 ...
- 嵌入式Web服务器boa在ARM平台的移植步骤
1.下载http://www.boa.org/ 2.解压tar xzf boa-0.94.13.tar.gz 3.编译cd boa-0.94.13/src./configure 生成了makefile ...
- 三种嵌入式web服务器(Boa / lighttpd / shttpd)的 linux移植笔记
一:移植Boa(web服务器)到嵌入式Linux系统 一.Boa程序的移植 1.下载Boa源码 下载地址: http://www.boa.org/ 目前最新发行版本: 0.94.13 ...
- [置顶] ARM-Linux下WEB服务器Boa的移植、配置和运行测试
Linux下使用的轻量级WEB服务器主要有:lighttpd.thttpd.shttpd和boa等等,而Boa是使用最为广泛的轻量级WEB服务器之一(当然,阿帕奇是世界使用排名第一的Web服务器软件) ...
- 嵌入式web服务器-thttpd
交叉编译thttpd http://lakie.blog.163.com/blog/static/45185220201162910432330/ thttpd安装与调试 http://blog.cs ...
- 移动物体监控系统-sprint4嵌入式web服务器开发
一.BOA嵌入式服务器的移植 step1:下载BOA服务器并解压,进入boa下面的src目录,执行./configure生成必须的配置文件以及Makefile step2:修改Makefile文件 c ...
- Mozi.HttpEmbedded嵌入式Web服务器
Mozi.HttpEmbedded 嵌入式Web服务器 项目介绍 Mozi.HttpEmbedded是一个基于.Net构建的嵌入式Web服务器,为.Net App提供web服务功能. 嵌入式的目标不是 ...
- 学号20145332 《信息安全系统设计基础》实验五 简单嵌入式WEB服务器实验
实验目的 掌握在 ARM 开发板实现一个简单 WEB 服务器的过程. 学习在 ARM 开发板上的 SOCKET 网络编程. 学习 Linux 下的 signal()函数的使用. 实验内容 学习使用 s ...
随机推荐
- Java实现PV操作 | 哲学家进餐问题
运行结果: Java代码: public class Main { public static void main(String[] args) { Global global=new Global( ...
- C语言中常见的图形打印总结
直角三角形(靠右直立) 示例实现代码如下: int main(){ int n; int i,j; cin >> n; if(n<= 0){ cout << " ...
- centos7 安装 bugfree3
. 安装apache yum install httpd . 安装mysql wget -i -c http://dev.mysql.com/get/mysql57-community-release ...
- shell 只读变量
test.sh: #!/bin/bash myUrl="http://www.google.com" readonly myUrl myUrl="http://www.r ...
- win10 关闭开机密码
在运行对话框里输入:netplwiz 控制面板(control)>电源选项>更改计算机休眠时间-选为 从不
- Android Studio 本地化操作
1.打开 string.xml 文件,在右上角,点 open-editor 2.点左上角的“地球”图标,就会弹出选择国家列表,输入zh会自动筛选,能很快选到中国简体中文 3.选择后,会在原来的列表中添 ...
- python发送钉钉机器人脚本
#!/usr/bin/python# -*- coding: utf-8 -*-import requestsimport jsonimport sysimport os headers = {'Co ...
- java复制对象之深拷背
在java开发中,有时我们需要复制对象,并且确保修改复制得到的对象不会影响原来的对象. 于是,有些人可能会写出类似以下的代码: public class CloneTest { public stat ...
- [Beta阶段]第五次Scrum Meeting
Scrum Meeting博客目录 [Beta阶段]第五次Scrum Meeting 基本信息 名称 时间 地点 时长 第五次Scrum Meeting 19/05/10 新主楼F座2楼 50min ...
- SpringMVC(十四):SpringMVC 与表单提交(post/put/delete的用法);form属性设置encrypt='mutilpart/form-data'时,如何正确配置web.xml才能以put方式提交表单
SpringMVC 与表单提交(post/put/delete的用法) 为了迎合Restful风格,提供的接口可能会包含:put.delete提交方式.在springmvc中实现表单以put.dele ...