声明
华清远见教育集团 15年专注高端IT培训 做良心教育,做专业教育,做受人尊敬的职业教育
创客学院官网:http://www.makeru.com.cn/
华清远见创客学院嵌入式课程链接:http://www.makeru.com.cn/emb
华清远见创客学院物联网课程链接:http://www.makeru.com.cn/iot
概述
CGI 是Web 服务器运行时外部程序的规范,按CGI 编写的程序可以扩展服务器功能。CGI 应用程序能与浏览器进行交互,还可通过数据库API 与数据库服务器等外部数据源进行通信,从数据库服务器中获取数据。格式化为HTML文档后,发送给浏览器,也可以将从浏览器获得的数据放到数据库中。几乎所有服务器都支持CGI,可用任何语言编写CGI,包括流行的C、C ++、VB 和Delphi 等。CGI 分为标准CGI 和间接CGI两种。标准CGI 使用命令行参数或环境变量表示服务器的详细请求,服务器与浏览器通信采用标准输入输出方式。间接CGI 又称缓冲CGI,在CGI 程序和CGI 接口之间插入一个缓冲程序,缓冲程序与CGI 接口间用标准输入输出进行通信。
总之,CGIC是一个功能比较强大的支持CGI开发的标准C库,并支持Linux, Unix 和Windows等多操作系统。
框图
CGI程序的工作一般就是接收表单数据,进行数据处理,最后根据处理结果生成新的页面返回给浏览器。
源码分析
root@linux:~/tool/cgic205# tree -a
.
├── capture.c
├── cgic.c
├── cgic.h
├── cgic.html
├── cgictest.c
├── license.txt
├── Makefile
├── readme.txt
└── support.txt
0 directories, 9 files
cgic.h:头文件;
cgic.c:CGIC的源代码文件;
cgictest.c:CGIC库的作者提供的一个CGI程序例子;
capture.c:用于调试CGI程序的工具;
Makefile:安装CGIC的脚本文件;
可以看到,整个库实际上就是cgic.c一个文件,可以说是非常的精炼。可以把CGIC安装为操作系统的一个动态链接库,这样我们每次编译的时候,就不需要有cgic.c这个源文件了。但是由于需要(以后将会看到),我们将修改cgic.c代码,所以我们不把它安装进系统。每次编译的时候,只要把cgic.c和cgic.h放到当前文件夹就好了。
用户操作流程分析
用户通过客户端应用(浏览器)向web服务发送一个get请求,web服务器返回一个默认的静态html页面;用户想在这个基础上进一步操作,比如用户登录,需要填写 ‘用户名-密码’ 吧,这样提交的信息就以form表单的形式从web服务器,再通过CGI接口向服务器上的应用发送。CGI就是这么一个中间机制,这里简单理解就是讲前端产生的html语言转换成应用层的c语言,实现交互。
CGIC的移植过程
源码移植
-
.解压
root@linux:~/tool# tar -xvf cgic205.tar.gz
-
修改交叉编译环境
CFLAGS=-g -Wall #CROSS_COMPILE= CROSS_COMPILE=arm-linux- CC=$(CROSS_COMPILE)gcc AR=$(CROSS_COMPILE)ar RANLIB=$(CROSS_COMPILE)ranlib LIBS=-L./ -lcgic all: libcgic.a cgictest.cgi capture install: libcgic.a cp libcgic.a /usr/local/lib cp cgic.h /usr/local/include @echo libcgic.a is in /usr/local/lib. cgic.h is in /usr/local/include. libcgic.a: cgic.o cgic.h rm -f libcgic.a $(AR) rc libcgic.a cgic.o $(RANLIB) libcgic.a #mingw32 and cygwin users: replace .cgi with .exe cgictest.cgi: cgictest.o libcgic.a #gcc cgictest.o -o cgictest.cgi ${LIBS} $(CC) $(CFLAGS) cgictest.o -o cgictest.cgi ${LIBS} capture: capture.o libcgic.a #gcc capture.o -o capture ${LIBS} $(CC) $(CFLAGS) capture.o -o capture ${LIBS} clean: rm -f *.o *.a cgictest.cgi capture
-
编译cgi源码
root@linux:~/tool/cgic205# make arm-linux-gcc -g -Wall -c -o cgic.o cgic.c rm -f libcgic.a arm-linux-ar rc libcgic.a cgic.o arm-linux-ranlib libcgic.a arm-linux-gcc -g -Wall -c -o cgictest.o cgictest.c #gcc cgictest.o -o cgictest.cgi -L./ -lcgic arm-linux-gcc -g -Wall cgictest.o -o cgictest.cgi -L./ -lcgic arm-linux-gcc -g -Wall -c -o capture.o capture.c #gcc capture.o -o capture -L./ -lcgic arm-linux-gcc -g -Wall capture.o -o capture -L./ -lcgic
-
将capture和cgictest.cgi拷贝到nfs共享根目录下的boa/cgi-bin/目录中
cp capture /nfs/rootfs/boa/cgi-bin/ cp cgictest.cgi /nfs/rootfs/boa/cgi-bin/
-
测试效果-运行开发板 ,先运行boa服务器(后台运行)
[root@farsight boa]# ./boa & [root@farsight boa]# [01/Jan/1970:00:06:59 +0000] boa: server version Boa/0.94.13 [01/Jan/1970:00:06:59 +0000] boa: server built Nov 29 2017 at 11:22:26. [01/Jan/1970:00:06:59 +0000] boa: starting server pid=1205, port 80
-
在工作站的浏览器地址栏输入http://192.168.2.10/cgi-bin/cgictest.cgi, (直接指定要运行的程序)
(指定网页运行举例:http://192.168.2.10/pass.html 板子ip/网页名)
问题与解决思路
-
Unable to connect
Firefox can’t establish a connection to the server at 192.168.1.100.
Boa服务器没有运行: -
404 在boa的/cgi-bin目录下找不到对应的cgi文件或在www目录下找不到对应的html文件
404 Not Found
The requested URL /cgi-bin/cgictest.cgi was not found on this server
404 Not Found
The requested URL /index.html was not found on this server.
进一步项目移植
移植步骤
-
编写 mycgitest.c
#include<stdio.h> #include "cgic.h" #include <string.h> #include <stdlib.h> int cgiMain() { #ifdef DEBUG printf("Enter cgiMain() .....\n"); #endif /* DEBUG */ cgiHeaderContentType("text/html"); /* Top of the page */ fprintf(cgiOut, "<HTML><HEAD>\n"); fprintf(cgiOut, "<TITLE>My First CGI</TITLE></HEAD>\n"); fprintf(cgiOut, "<BODY><H1>Hello CGIC......</H1>\n"); fprintf(cgiOut,"<H3> by zhuzhongwei </H3>\n"); fprintf(cgiOut, "</BODY></HTML>\n"); return 0; }
-
Makefile 修改
CFLAGS=-g -Wall CROSS_COMPILE=arm-linux- #CROSS_COMPILE= CC=$(CROSS_COMPILE)gcc AR=$(CROSS_COMPILE)ar RANLIB=$(CROSS_COMPILE)ranlib LIBS=-L./ -lcgic NFSBOA_CGIBIN=/nfs/rootfs/boa/cgi-bin/ NFSBOA_WWWDIR=/nfs/rootfs/boa/www/ all: libcgic.a capture cgictest.cgi \ mycgitest.cgi login.cgi install: libcgic.a cp libcgic.a /usr/local/lib cp cgic.h /usr/local/include @echo libcgic.a is in /usr/local/lib. cgic.h is in /usr/local/include. libcgic.a: cgic.o cgic.h rm -f libcgic.a $(AR) rc libcgic.a cgic.o $(RANLIB) libcgic.a #mingw32 and cygwin users: replace .cgi with .exe cgictest.cgi: cgictest.o libcgic.a $(CC) cgictest.o -o cgictest.cgi ${LIBS} capture: capture.o libcgic.a $(CC) capture.o -o capture ${LIBS} mycgitest.cgi: mycgitest.o libcgic.a $(CC) mycgitest.o -o mycgitest.cgi ${LIBS} login.cgi: login.o libcgic.a $(CC) login.o -o login.cgi ${LIBS} nfsdeal: mv *.o ./obj/ mv *.a *.cgi capture ./cgi-bin/ sudo cp ./cgi-bin/* $(NFSBOA_CGIBIN) sudo cp ./login/* $(NFSBOA_WWWDIR)/images/login/ sudo cp login.html $(NFSBOA_WWWDIR) clean: rm -f *.o *.a cgictest.cgi capture rm -f ./cgi-bin/* ./obj/*
-
将capture和mycgitest…cgi拷贝到主机的/nfs/rootfs/boa/cgi-bin目录下。
cp capture mycgitest.cgi /nfs/source/rootfs/boa/cgi-bin -
浏览器测试 输入url http://192.168.2.10/cgi-bin/mycgitest.cgi
问题与解决思路
- 问题一:
1、A9服务器 没有运行 ./smart_storage
2、A9和CGI的进程间通信失败:
注意查看进程间通信的ftok获得的秘钥是否是一致的。
2. 问题二:404的错误:
诊断:html网页找不到对应的cgi程序;
解决思路:
1、右键、查看网页源代码,确定IP地址没有问题
2、查看form表单,form表单对应的/cgi-bin/xxx.cgi在boa的cgi-bin目录下是否存在;
项目移植(完整版)
-
添加新的文件到cgi源码目录
-
修改Makefile编译规则,把刚才那些文件添加到Makefile编译项
CC=arm-none-linux-gnueabi-gcc AFLAGS=-Wall -g LDFLAGS= -L ./lib OBJS= capture.cgi a9_beep.cgi zigbee_fan.cgi\ a9_led.cgi a9_seg.cgi \ env1.cgi setEnv.cgi run:$(OBJS) $(OBJS):%.cgi:%.c $(CC) $(AFLAGS) $< cgic.c -o $@ $(LDFLAGS) install: $(CC) $(AFLAGS) login.c -o login.cgi mv *.cgi ./out/ sudo cp ./out/*.cgi /nfs/rootfs/boa/cgi-bin .PHONY:clean clean: rm ./out/*.cgi
-
编译并将目标文件移动到nfs根目录下
-
查看效果,用户通过浏览器访问开发板IP,web服务器返回一个默认页面