当前位置:文档之家› 快速搭建嵌入式Web服务器

快速搭建嵌入式Web服务器


总结:数据交互的流程
在搜索文件的过程中,还涉及到了对文件的读写 struct fs_file * fs_open(char *name) void fs_close(struct fs_file *file) int fs_read(struct fs_file *file, char *buffer, int count)
编译器:
Keil4.12
可执行的二进制文件
软件平台
底层协议分析时可以 使用数据抓包软件
WEB基础知识
TCP/IP分层结构
HTTP 应用层 应用层
软件
TCP.UDP
传输层
传输层
IP.IGMP.ICMP
网络层
网络层
Ethernet MAC
硬件
数据链路层
数据链路层
Ethernet PHY
物理层
物理层
WEB应用程序的实现
HTTP 超文本传输协议
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "/TR/xhtml1/DTD/xhtml1transitional.dtd"> <html xmlns="/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>hello</title> </head> <body> hello world </body> </html> http格式: <arg> con.. </arg>
初始化部分 主体部分
先知道这个过程即可,其他知识具体用到时再作介绍
开始编写第一个程序
准备工作
在浏览器中输入192.168.14.20,回车后,到底发送了什么数据,格式怎么样?
在开始编写第一个程序之前,我们来看看WEB客户端发送的第一个数据包到底是什么?
这里的第10个数据包即使我们需要知道的数据包
小贴士:在一些计算机操作系统上,cgi或者是ssi是一个脚本程序或者是一个 C等其他语言实现的程序。在计算机上SSI的标签可能都是标准的字符集,但是 在嵌入式系统中我们可以更灵活的使用这些。甚至是对部分功能进行精简,使得 代码量能减小。
现在开始动态网页的实现—表单方式
<form id="login" name="login" method="get" action="login.cgi"> <table width="200" border="1" align="center"> <tr> <td>username</td> <td><label> <input name="username" type="text" id="username" accesskey="u" value="root" size="10" maxlength="10" /> </label></td> </tr> <tr> <td>passwd</td> <td><label> “value”? <input name="passwd" type="password" id="passwd" accesskey="p" size="10" maxlength="10" /> </label></td> </tr> 提交一个表单 <tr> <td colspan="2"><label> <div align="center"> <input type="submit" name="Submit" value="提交" /> <input name="reset" type="reset" id="reset" value="重置" /> </div> </label></td> </tr> </table> 点击“提交”后,数据发送格式如何? </form>
const tCGI g_px_cgi_uris_config[] = { { "/login.cgi", LoginCGIHandler }, };
// CGI_INDEX_LOGIN
static char * LoginCGIHandler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[])
动手编写一个CGI处理程序(续)
第四步:编写“LoginCGIHandler ()” 函数实体: 需要找的关键字
找到的参数索引号
s32_param = FindCGIParameter("passwd", pcParam, iNumParams); if(s32_param != -1) { DecodeFormString(pcValue[s32_param], (char *)u8_passwd, 10+1); }
此文部分内容摘至“E书时空”
SSI?
SSI与CGI相同,也可以理解为一段程序,帮助CGI程序更好的完成网页数据的 交互过程。使得CGI返回给客户端消息时,处理更容易和轻松。 在物理上,SSI只是一些标识符,但是有它自己的格式如下所示: SSI tags 格式: <!--#tag--> 其中tag可以用户自定义,系统默认支持最大8个字节 长度的标识符,用户可以修改定义宏来支持更长的标识,但建议越短越好。 工作原理: 服务器在接收到一个请求后,会在网页数据中搜索以上格式的字符,并 记录这些tag标识,在服务器处理完任务后需要返回给客户机数据时,会找系统已经 注册了的tag,并在相应的tag-->后添加所需要的数据,最后把数据再发送给客户机。 实现了整个网页动态交互的功能。
打开“[模板]web-server-demo的过程
初始化重要函数
lwIPInit(); typedef char *(*tCGIHandler)(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]);
动手编写一个CGI处理程序
目标:实现一个用户登入界面 第一步:编写相应的网页,该网页当中应该包含一个表单,表单中还应该包含 一些关键字(见例程)。最后该应该包含一个提交按钮。 第二步:使用makefsfile工具把该网页目录转换成“网络文件系统”这里有别于NFS 第三步:在程序中添加cgi程序,如下代码:可参考 /src/ssi_cgi_handle.c文件中的相关代码 #define CGI_INDEX_LOGIN 0
把找到的参数值存入缓存中
注意这里的+1?
第五步: 编译,下载程序。观察效果,如有问题马上调试。
表单提交的另一种方式 -- POST
在前面的表单代码中, method=“”定义了该表单提交的方式。get or post ? 在一般的嵌入式WEB开发中,用的最多的是get方式,get我们可以理解成客户端 需要向服务器获取什么文件。这种方式的好处就是一问一答,对服务器来会说可以 很容易的处理这些问题。--这里的关键是使用get方式,客户机的需求一般只需要发送 一个数据包就可以把自己需要的信息说明白。 的确是一个数据包,lwip默认的配置只把缓冲区开了256个字节,去掉协议部分, 数据部分只有200字节左右,这对于大的数据包来说是很危险的。因为多余的数据 部分会被无情的截掉。 但从另外一个角度来说,对于一个确定的嵌入式WEB服务器应用,它只做自己份 内的事,200个字节己足够实现功能,何乐而不为呢?多余的ram空间完全可以给应用 程序使用。 但想实现POST,那这200个字节就太少了。POST方式主要是用于客户机有大量 数据想传送给服务器,传输完毕之后会自动再发送一个GET方法向服务器获取,这么 大的数据是否没有传错?这个问题的答案必须由服务器回答,应为也只有服务器才知道 数据接收有没有错误! 问题出现了:POST方法可能需要多个数据包连续的发送,而现有的Lwip不支持
有时间讲
表单提交的另一种方式 – POST(续)
此POST方式,怎么办? 只有分析POST方法协议,修改Lwip中HTTP底层协议,使得支持POST方法 Lwip中对POST方法的支持具体请查看源程序。 这里提供一个对于不明协议,如何对数据进行分析的一般处理方法!!!
开发所需软硬件平台
Cortex-M3 : LM3S6432 CODE : 96K单周期 RAM : 32K SRAM
RJ45接口
USB : 供电及其 JTAG调试接口
串口调试 115200 8N1
JTAG调试底板
硬件平台
网页编辑软件:
Dreamweaver 8
网页转换成二进制文件: Makefsfile(dos命令)
相关主题