一、boa服务器的移植

1、源码下载

1.1 boa简介:

其可执行代码只有大约60KB左右,Boa是一个单任务的HTTP服务器,Boa只能依次完成用户的请求,而不会fork出新的进程来处理并发连接请求。Boa支持CGI。

Boa的设计目标是速度和安全。(CGI只是一个进程,用来提供接口),自动目录生成和自动文件枪支进行拼接。

Boa的主要设计目标是速度和安全性。安全性在“不能被恶意用户破坏”的意义上,不是“细粒度访问控制和加密通信”。

特点:可靠性和可移植性,Boa不是作为功能强大的服务器。

开发平台:GNU / Linux是目前的开发平台。

推荐:GoAhead   Apache2

跨平台移植三部曲:

1、./configure生成一个Makefile      ./configure  --prefix   --host

2、make

3、make install

2、解压源码:

已免费开源在我发布的资源当中

  tar -xvf boa-0.94.13.tar.gz

3、进入源码目录下的src目录:

  cd boa-0.94.13/src/

在源码目录下配置与编译。执行

./configure

这是根据configure.in文件进行一系列的配置,生成config.status,configure,和Makefile文件。

如果无法执行,考虑权限,修改该目录下的configure的属性为可执行 chmod 755 configure

4、make 编译源码:

问题1:

目录: boa-0.94.13/src$ make

yacc  -d boa_grammar.y

make: yacc: Command not found

make: *** [y.tab.c] Error 127

解决方法:

/boa-0.94.13/src$ sudo apt-get install bison

问题2:

yacc  -d boa_grammar.y

gcc  -g -O2 -pipe -Wall -I.   -c -o y.tab.o y.tab.c

......

lex  boa_lexer.l

make: lex: Command not found

make: *** [lex.yy.c] Error 127

解决方法:

/boa-0.94.13/src$ sudo  apt-get install flex

WARNING: The following packages cannot be authenticated!

libfl-dev flex

Install these packages without verification? [y/N]

E: Some packages could not be authenticated

注意加参数-f 自动搜索依赖,下面选择y  : sudo  apt-get install flex -f

Do you want to continue? [Y/n] y

WARNING: The following packages cannot be authenticated!

libfl-dev flex

Install these packages without verification? [y/N] y

问题3:

util.c: In function ‘get_commonlog_time’:

util.c:100:39: error: pasting "t" and "->" does not give a valid preprocessing token

time_offset = TIMEZONE_OFFSET(t);                                  ^

compat.h:120:30: note: in definition of macro ‘TIMEZONE_OFFSET’

#define TIMEZONE_OFFSET(foo) foo##->tm_gmtoff                     ^

make: *** [util.o] Error 1

问题描述:在compat.h文件中的宏定义问题:  ‘TIMEZONE_OFFSET

解决方法:

修改 boa-0.94.13/src$ vi compat.h  +120

找到

#define TIMEZONE_OFFSET(foo) foo##->tm_gmtoff

修改成

#define TIMEZONE_OFFSET(foo) (foo)->tm_gmtoff

将boa.c中的 vi   boa.c

225     #if 0     //注释掉

226         if (setuid(0) != -1) {

227             DIE("icky Linux kernel bug!");

228         }

229     #endif

这三行注释掉,否则boa启动时会出现“boa.c:226 - icky linux kernel bug!: No suchfile or directory错误”

清除之前编译的内容 make clean (防止某些依赖的信息出现问题)

重新make

再次boa-0.94.13/src$ make

make: Nothing to be done for `all'.

make主要检查的是时间戳, 只要target比依赖的文件时间靠后它就认为不需要编译

5.建立安装目录

  sudo mkdir -p /boa   /boa/www   /boa/cgi-bin   /boa/log  将src/defines.h中的#define SERVER_ROOT "/etc/boa"修改为#define SERVER_ROOT "/boa"

(这样boa程序启动时会在/boa目录下寻找boa.conf配置文件,并且将/boa文件夹作为服务器的根目录)。

将需要的文件复制到安装目录中

  将boa-0.94.13/src目录下生成的boa、boa_indexer二进制文件复制到/boa下sudo  cp  boa boa_indexer  /boa将boa-0.94.13目录下的boa.conf文件复制到/boa下sudo  cp  boa.conf  /boa可选项: arm-linux-strip boa(去掉boa中的调试信息,只是减小文件的大小可以执行也可以不执行)将/etc/mime.types复制到/boa目录下sudo cp  /etc/mime.types  /boa

6、返回boa的顶层目录  --- 修改配置文件

回到 boa-0.94.13 目录,

vi boa.conf, //几乎全部指定到boa的目录下,这样方便我们进行管理

重新指定一些文件的生成路径,因为重新指定这些路径后会帮助我们深刻的理解关于boa服务器的工作机制,对照以下代码进行修改:

 Port  80  User  0  Group 0  ErrorLog /boa/log/error_log  AccessLog /boa/log/access_log   DocumentRoot /boa/www  UserDir public_html  DirectoryMaker /boa/boa_indexer   //修改MimeTypes /boa/mime.types   //修改Alias /doc /usr/docScriptAlias /cgi-bin/ /boa/cgi-bin/ 

7.建立测试页面

(1)index.html  ,将index.html 放在/boa/www目录下

sudo cp index.html image.jpg /boa/www
 <html> <body> <h3>this is a test!</h3><br/> <img src="data:image.jpg"/> <h3>tree picture</h3><br/> <a href="/cgi-bin/test.cgi">to cgi page</a>    //指定了cgi可执行文件存放的路径,默认从/boa的根目录开始查找</body> </html>  

注意: 笔记本打开,另存为utf-8格式,自己添加一张图片到当前的目录下

(2)test.c, 使用gcc -o test.cgi test.c,将test.c编译生成test.cgi,后缀为cgi的类型

编译后得到的test.cgi放在/boa/cgi-bin目录下,

 sudo cp test.cgi  /boa/cgi-bin/
  #include <stdio.h> int main() { printf("Content-type:text/html\n\n"); //这句一定要加上 printf("<html><body>"); printf("<font style=\"color:red; font-size:30px;\">Hello, CGI!</font><br/>"); printf("<a href=\"/index.html\">return index.html</a>"); printf("</body></html>"); return 0; } 

8、查看/boa目录下所有的文件:

10、测试效果

进入/boa目录,使用./boa来运行boa服务器(当然也可将/boa路径加入系统PATH环境变量,这样不用进入/boa目录,直接输入boa就可以了)

在浏览器中输入http://127.0.0.1/便可访问到默认的页面index.html,

  或:    http://192.168.1.200:80http://localhostip:port

点击index.html页面中的超链接便可访问到cgi测试页面,点击test.cgi中的超链接又可返回index.html页面。

(1)index.html页面

fengjunhui@ubuntu:/boa$ ./boa

[19/Jul/2017:08:44:28 +0000] log.c:73 - unable to dup2 the error log: Bad file descriptor

解决方法:

这个问题其实就是你没有创建log文件夹,以及文件夹下的log_error和access_error文件引起的。只要在boa.conf中找到这两个文件的信息,将其路径改成自己需要的路劲,并在相应的位置创建对应文件就OK。

62 ErrorLog /boa/log/error_log

74 AccessLog /boa/log/access_log

fengjunhui@ubuntu:/boa$ ls  发现有log目录

boa  boa.conf  boa_indexer  cgi-bin  log  mime.types  www

问题描述

log.c:73   unable to dup2 the error log: Bad file descriptor

问题解决:

Vi  log.c  +73

扩展:

函数名: dup2

功能: 复制文件描述符

用法: int dup2(int oldfd,int newfd);

修改 src/log.c

注释掉

if (dup2(error_log, STDERR_FILENO) == -1) {

DIE("unable to dup2 the error log");

}

为:

71 #if 0

72         /* redirect stderr to error_log */

73         if (dup2(error_log, STDERR_FILENO) == -1) {

74             DIE("unable to dup2 the error log");

75         }

76 #endif

/boa目录下重新执行  ./boa 执行

Cannot open /boa/log/access_log for logging: logfile open: Permission denied

出错,因为不是root用户(虚拟机),权限不够。(A9开发板默认登录为root用户,不需要加sudo)

sudo ./boa

然后再./boa  此时boa服务器就已经启动,打开ubuntu浏览器,输入ubuntu的ip地址,就可以看到你放在/var/www里的网页了。ok

测试结果:

http://127.0.0.1/index.html

以上是在PC上部署BOA的大致步骤,仅供参考。

问题描述:

fengjunhui@ubuntu:/boa$ sudo ./boa

[19/Jul/2017:13:44:11 +0000] boa.c:194 - unable to bind: Address already in use

如何关闭boa服务器:

fengjunhui@ubuntu:~$ ps -axj | grep "boa"

2102 24862 24860 24255 pts/18   24255 S    65534   0:00 ./boa

2102 25735 25733 24255 pts/18   24255 S    65534   0:00 ./boa

25753 25793 25792 25753 pts/4    25792 S+    1000   0:00 grep --color=auto boa

kill -9 pid(boa)

fengjunhui@ubuntu:~$ sudo kill -9 24862

fengjunhui@ubuntu:~$ sudo kill -9 25733

重新启动boa,再次通过浏览器访问cgi,访问成功!

fengjunhui@ubuntu:~/Boa-0.94/boa-0.94.13/src$ sudo cp boa_indexer boa /boa

cp: cannot create regular file ‘/boa/boa’: Text file busy

cp并不改变目标文件的inode,事实上它的实现是这样的:

# strace cp test2 test 2&1 | grep open.*test

open("test2", O_RDONLY|O_LARGEFILE) = 3

Linux由于Demand Paging机制的关系,必须确保正在运行中的程序镜像(注意,并非文件本身)不被意外修改,

因此内核在启动程序后会锁定这个程序镜像的inode。这就是为什么cp在用“O_WRONLYO_TRUNC”模式open目标文件时会失败。

而先rm再cp的话,新文件的inode其实已经改变了,原inode并没有被真正删除,直到内核释放对它的引用。

fengjunhui@ubuntu:/boa$ sudo rm boa

sudo cp boa_indexer boa /boa

扩展部分:

11、移植到A9开发板上:

(注意修改源码,具体的现象可以参考视频,遇到问题推荐自己通过百度解决问题,会查资料也是一种能力)

  1. 移植boa到嵌入式linux上的方法和上面几乎一样,具体做法是\在

./configure

生成Makefile后将Makefile中的

CC = gcc   CPP=gcc -E

改为

CC = arm-linux-gcc,

CPP = arm-linux-gcc -E,

然后make就可以了。

(2)重新拷贝修改后的文件:

将boa-0.94.13/src目录下生成的boa、boa_indexer二进制文件复制到/boa下

将boa-0.04.13目录下的boa.conf文件复制到/boa下

将/etc/mime.types复制到/boa目录下

将test.cgi放在/boa/cgi-bin目录下,

将index.html image.jpg 放在/boa/www目录下

(3)拷贝文件到rootfs文件系统目录下:

cd boa 进入boa文件目录

移植到开发板后:

[root@fengjunhui boa]:~$ ./boa

No such user: nobody

解决方法:

sudo vi boa.conf

(1)Group的修改

修改 Group nogroup  为 Group 0

(2)user的修改

修改 User nobody 为 User 0

[root@fengjunhui boa]:~$ ./boa

问题描述:

[01/Jan/1970:00:23:10 +0000] boa.c:211 - getpwuid: Success

[01/Jan/1970:00:00:39 +0000] boa.c:211 - getpwuid: No such file or directory

解决:修改src/boa.c

注释掉下面两句话:

#if 0

if (passwdbuf == NULL) {

DIE(”getpwuid”);

}

if (initgroups(passwdbuf->pw_name, passwdbuf->pw_gid) == -1) {

DIE(”initgroups”);

}

#endif

(2)移植boa到嵌入式linux后,在启动时若出现“gethostbyname:: Success

"然后程序退出,则需在原boa.conf文件中增加一行:

ServerName  www.your.org.here

然后重新运行boa,然后在主机浏览器输入开发板网址(http://开发板ip:port)

[root@fengjunhui ]:~$ cd boa

[root@fengjunhui boa]:~$ ls

boa          boa_indexer  log          www

boa.conf     cgi-bin      mime.types

[root@fengjunhui boa]:~$ ./boa

[01/Jan/1970:00:00:24 +0000] boa: server version Boa/0.94.13

[01/Jan/1970:00:00:24 +0000] boa: server built Jul 19 2017 at 23:07:48.

[01/Jan/1970:00:00:24 +0000] boa: starting server pid=1185, port 80

[root@fengjunhui boa]:~$ [01/Jan/1970:00:01:30 +0000] request from 192.168.8.223 "GET /favicon.ico HTTP/1.1" ("/boa/www/favicon.ico"): document open: No such file or directory

[01/Jan/1970:00:01:30 +0000] request from 192.168.8.223 "GET /favicon.ico HTTP/1.1" ("/boa/www/favicon.ico"): document open: No such file or directory

这个问题不影响使用:

问题描述:

[01/Jan/1970:00:01:34 +0000] cgi_header: unable to find LFLF

出错位置

cgi_procee_header()

对于错误 cgi_header: unable to find LFLF的补充

浏览器中显示502 Bad Gateway

The CGI was not CGI/1.1 compliant.

解决方法:在Ubuntu端和A9端的交叉编译环境不一样,最好链接为静态库,这样不用单独提供库的支持

<3>编译方式:arm-linux-gcc -static -o xxx.cgi  xxx.c

可能的原因:

<1>输出MIME格式错误,结尾一定要有两个换行符

printf("Content-Type:text/html\n\n")

<2>权限错误

chmod 777 var/www/cgi-bin/xxx.cgi

<3>编译方式:arm-linux-gcc -static -o xxx.cgi  xxx.c

<4>备用方案:代码本身错误也会引起这个问题。实践中这个问题困扰了很久,一个字符串数组的处理有了问题, 提示的错误信息却是这个,开始一直郁闷于格式和权限,也可能是调用的一个小函数有些问题而导致的。所以在遇到这个问题时,如果输出格式和权限都正确的情况下,检查代码是个很好的选择

测试:

在Ubuntu上输入你板子的ip: http://192.168.1.100/

OK ,实现了和直接在Ubuntu上操作一样的结果

输入指定的路径去访问:

http://192.168.1.100/index.html

http://192.168.1.100/pass.html    跳转访问到指定的cgi

指定是OK的。

可选项:   ***----->然后给boa瘦身

arm-none-linux-gnueabi-strip boa

fengjunhui@ubuntu:~/smartstorage/boa-0.94/boa-0.94.13/src$ arm-none-linux-gnueabi-strip boa

arm-none-linux-gnueabi-strip: Unable to recognise the format of the input file `boa'

我们并没有修改Makefile,那么这个时候编译生成的x86格式的boa

fengjunhui@ubuntu:~/smartstorage/boa-0.94/boa-0.94.13/src$ file boa

boa: ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=95bed4fc9481ca5ac84616c6cfb2578f4e4d1a2f, not stripped

F

错误记录:

line: 1: Syntax error: word unexpected (expecting ")")

开发板上运行可执行程序报出错误:

line1: 1: Syntax error: word unexpected (expecting ")")

解决思路:

1.编译器的问题

用arm-linux-gcc编译,可能原来是用gcc编译的。

假如是脚本,#!/bin/sh 改 #!/bin/bash试试。

2.文件完整性

重新烧写或上传一遍。

3.编译命令问题 

比如我的一个测试程序test.c :

arm-linux-gcc -o test.o -c test.c    //编译为目标文件

arm-linux-gcc -o test.o test.c        //编译为可执行文件

boa.conf 内容详解:

25 Port 80

监听的端口号,缺省都是80,一般无需修改。注意,如果你的httpd服务器已经开启,那么你必须关掉或者重新设定端口号,

当你修改了模式http端口那么访问的时候要加上端口号,如http://localhostip:port

作为哪个用户运行,即它拥有该用户的权限,一般都是nobody,需 要 /etc/passwd中有nobody用户

User nobody

查看: vi /etc/passwd   18 nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin

作为哪个用户组运行,即它拥有该用户组的权限,一般都是nogroup,需要在/etc/group文件中有nogroup组

Group nogroup

查看:  vi /etc/group   39 nogroup:x:65534:

是否使用本地时间。如果没有注释掉,则使用本地时间。注释掉则使用UTC时间

UseLocaltime

是否记录CGI运行信息,如果没有注释掉,则记录,注释掉则不记录

VerboseCGILogs

服务器名字

ServerName www.chad.com

是否启动虚拟主机功能,即设备可以有多个网络接口,每个接口都可以拥有一个虚拟的Web服务器。一般注释掉,即不需要启动

VirtualHost

非常重要,HTML文档的主目录。如果没有以/开始,则表示从服务器的根路径开始。注意,如果此处设置不正确,将不能打开网页

DocumentRoot /var/www

如果收到一个用户请求的话,在用户主目录后再增加的目录名

UserDir public_html

HTML目录索引的文件名,也是没有用户只指明访问目录时返回的文件名

DirectoryIndex index.html

当HTML目录没有索引文件时,用户只指明访问目录时,boa会调用该程序生成索引文件然后返回给用户,因为该过程比较慢最好不执行,

可以注释掉或者给每个HTML目录加上DirectoryIndex指明的文件

DirectoryMaker /usr/lib/boa/boa_indexer

如果DirectoryIndex不存在,并且DirectoryMaker被注释,那么就用Boa自带的索引生成程序来生成目录的索引文件并输出到下面目录,

该目录必须是Boa能读写

DirectoryCache /var/spool/boa/dircache

一个连接所允许的HTTP持续作用请求最大数目,注释或设为0都将关闭HTTP持续作用

KeepAliveMax 1000

HTTP持续作用中服务器在两次请求之间等待的时间数,以秒为单位,超时将关闭连接

KeepAliveTimeout 10

指明mime.types文件位置。如果没有以/开始,则表示从服务器的根路径开始。可以注释掉避免使用mime.types文件,此时需要用AddType在本文件里指明

MimeTypes /etc/mime.types

文件扩展名没有或未知的话,使用的缺省MIME类型

DefaultType text/plain

提供CGI程序的PATH环境变量值

CGIPath /bin:/usr/bin:/usr/local/bin

将文件扩展名和MIME类型关联起来,和mime.types文件作用一样。如果用mime.types文件,则注释掉,如果不使用mime.types文件,则必须使用

AddType application/x-httpd-cgi cgi

指明文档重定向路径

Redirect /bar http://elsewhere/feh/bar

为路径加上别名

Alias /doc /usr/doc

非常重要,指明CGI脚本的虚拟路径对应的实际路径。一般所有的CGI脚本都要放在实际路径里,用户访问执行时输入站点+虚拟路径+CGI脚本名

ScriptAlias /cgi-bin/ /var/www/cgi-bin/

用户可以根据自己需要,对boa.conf进行修改,但必须要保证其他的辅助文件和设置必须和boaconf里的配置相符,不然Boa就不能正常工作。

最后将修改好的boa.conf放在开发板上的/etc/boa目录下。

在上面的例子中,我们还需要创建日志文件所在目录/var/log/boa,

创建HTML文档的主目录/var/www,将mime.types文件拷贝到/etc目录,

创建CGI脚本所在目录/var/www/cgi-bin/。

mime.types文件用来指明不同文件扩展名对应的MIME类型,一般可以直接从Linux主机上拷贝一个,

大部分也都是在主机的/etc目录下,同样,将主机的mime.types文件拷贝到开发板上的/etc目录下。

【实战】物联网安防监控项目【2】———boa服务器的移植相关推荐

  1. 安防监控实现之boa服务器的移植

    文章目录 声明 boa服务器概述 boa服务器的移植 演示 boa服务器-PC平台演示 boa服务器-ARM平台演示 声明 华清远见教育集团 15年专注高端IT培训 做良心教育,做专业教育,做受人尊敬 ...

  2. 【实战】物联网安防监控项目【4】———从网页上控制A9的LED灯

    前言 学习了一个新知识,当然要记录一下啦.这两天学习了boa服务器.cgic标准库和html标签语言,又双叕解锁一个嵌入式的新玩法.cgic库是沟通C语言和html网页编程语言的一座桥梁,通过在lin ...

  3. 【实战】物联网安防监控项目———需求分析

    一.系统需求分析 1.目的 具体的应用场景展示 室内监控.家庭安保 小区安防监控 行车记录仪等 2.安防监控可以解决什么问题? 1).提供证据与线索 很多工厂.公司或银行发生偷盗或者事故,相关机关可以 ...

  4. 【实战】物联网安防监控项目【3】———CGI的移植及与学习html制作网页

    一.CGI的移植 CGIC移植部分笔记: CGIC是一个支持CGI开发的开放源码的标准C库,可以免费使用,只需要在开发的站点和程序文档中有个公开声明即可,表明程序使用了CGIC库,用户也可以购买商业授 ...

  5. 【实战】物联网安防监控项目【5】———把模拟数据传输到web网页、web显示mjpeg-streamer视频图像

    1.模拟数据传输到web 为了把硬件传感器上的数据上传到web网页,我们需要在跑linux服务器的开发板上写一个应用程序,并创建出几个线程来收集传感器检测到的数据,通过进程/线程间通信.boa与cgi ...

  6. 嵌入式安防监控项目总结

    目录 一.框架搭建 二.通信结构体设计 三.进程间通信 四.线程间通信 五.项目分工 六.项目联调 七.项目收获 一.框架搭建 这里放个图应该更有说服力,框架从硬件上就两块,A9和zigbee.并且我 ...

  7. 嵌入式安防监控项目——安防监控实现

    目录 一.视频流原理与移植 二.mjpeg-streamer视频图像的显示 2.1 MJPG简介 2.2环境 2.3查看我的摄像头信息 2.4驱动移植过程 2.5mjpg-stream的移植 (1)j ...

  8. 嵌入式安防监控项目——前期知识复习

    目录 一.概述 二.C语言 三.数据结构 四.IO进程 五.网络 六.ARM体系结构和接口技术 七.系统移植 八.内核驱动 一.概述 我再报班之前学过51和32,不过都是自学的.报班开始先从应用层入手 ...

  9. 安防监控实现之A9主框架的搭建

    文章目录 声明 线程 概念(意识) 分层分析 数据流分析 软件层次框架图 系统框架,线程关系 项目目录结构 数据描述 结构体描述 全局变量描述 主线程与各个子线程的搭建 主线程 各个子线程的函数 搭建 ...

最新文章

  1. Hyperledger Fabric权限进阶篇
  2. java list负载_java集合的扩容和负载因子的总结
  3. celery delay 没反应
  4. linux bash source 0,linux中BASH_SOURCE[0](转)
  5. 证明是一个偶像,数学家在这个偶像前折磨自己!
  6. 支付业务与技术架构学习总结(6)——对账系统的设计
  7. linux mc服务器 mod_使用阿里云服务器搭建饥荒联机版服务器(最新有效2020.2.9更新)...
  8. 基于小米球(Ngrok)实现外网访问
  9. Windows 修改注册表实现键位修改
  10. 北京54、西安80、CGCS2000、WGS84坐标系及区别
  11. Java字符串相关的类详解
  12. 深圳科目三辅城坳【手动挡】笔记
  13. 项目管理 : 如何做好建筑工程的施工成本管理
  14. MATLAB数值分析学习笔记:黄金分割法
  15. windows7 旗舰版 集成 usb3.0 NVMe 支持 AM4
  16. 微信分享appID注册一次后即绑定该应用?
  17. JAVA调用Excel公式和js判断选择计算有效集合
  18. 对数 java_Java对数函数及Java对数运算
  19. %2d与%.2d的区别
  20. 解决VSCode打开GBK编码文件乱码问题

热门文章

  1. 怎样让自我评价变成简历最出彩的地方?
  2. 事件监听的理解(ActionListener等)
  3. 搜索引擎的数据库设计
  4. 【果壳问答】学好高数有何用处?
  5. 基于像素的碰撞检测(移植到cocos2dx 3.x)
  6. 路是一步一步走出来的
  7. python画龙猫_宫崎骏王国——《龙猫》小梅(超详细零基础马克笔手绘教程)
  8. 直角坐标系中点的旋转【点绕点旋转】
  9. i3-1115G4 怎么样 相当于什么水平
  10. 暑期实践总结_李冰华