




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 . . . 第3章 嵌入式远程监控系统设计与实现1.1 课程设计目的通过本课程设计,要对嵌入式系统的开发有比较深入的学习和分析。通过对WEB编程、服务器的架设、驱动程序的开发这些步骤的深入研究,掌握构建一个完备的嵌入式系统的开发流程。1.2 课程设计要求通过本课程设计,熟练前面几章的容。在此基础上,编写相关驱动程序,以与CGI和数据处理程序完成基于WEB的嵌入式远程控制系统。通过本章的课程设计,可以初步了解一个嵌入式系统的基本构建过程,学习如何在ARM系统上搭建嵌入式服务器,并通过CGI控制外部设备的一般方法。1.3 系统简介嵌入式WEB 服务器与远程测控总的思想就是网络化仪器。完成的目标就
2、是设计基于Linux 操作系统的远程测控系统,并且讨论实践中的可行性,我们通过普通的浏览器就可以对远端现场的控制和测量以与获取远端现场的图像信息。使用嵌入式WEB 服务器的好处有这样几点:(1) 远程监控终端仅需要安装浏览器即可,无需开发专门的应用软件,降低系统成本。(2)浏览器所在的监控终端平台与WEB 所在的服务器平台无关,监控终端可以采用多种操作系统,真正实现了跨平台。(3)操作界面简单统一,表达直观生动,用户无需经过专门培训。(4)易于扩展新的功能,系统升级仅需在Web 服务器一端添加相应模块,与远程监控终端无关,降低系统升级维护费用。系统整体结构如下:图3.1 系统整体结构远程监控系
3、统所涉与的知识点很多,主要包括Linux 操作系统,核移植,文件系统的移植,服务器的移植,CGI 程序的移植,CGI 脚本的编写,设备驱动的调试和JavaScript 脚本,TCP 服务器与客户端,UDP 服务器与客户端,Java 中的多线程技术,Java 画图板与各种控件的添加。下面提供几已经做好的测控服务器的图片,先达到一个感性的认识。图3.2 是一个实时视频与温度测量远程监控系统,它将采集到的图像以与温度参数在网页中显示出来。图3.2 ARM9 远程实时视频与温度测量在这一章中我们将学习一个基本的嵌入式远程监控系统的搭建,由于涉与到的知识点较多,我们只能把其中最主要的知识简要地描述,更多
4、更详细的设计可以参考手册后面的参考文献。通过对本章的学习,读者可以了解架设一个嵌入式WEB服务器的全过程与其要点。1.4 嵌入式WEB服务器移植1.4.1 BOA的移植1、下载BOA源码下载地址: ./ 或者 0.94.13 下载 boa-0.94.13.tar.gz,注意:从boa 上下载的是boa-0.94.13.tar.gz,按照一般解压步骤进行解压:# tar xzf boa-0.94.13.tar.gz 2、生成Makefile文件生成Makefile 文件直接运行src/configure 文件。3、修改Makefile文件修改Makefile 文件修改 CC = g
5、cc 为 CC = arm-linux-gcc 修改 CPP = gcc - E 为 CPP = arm-linux-gcc -E4、编译# make 生成boa 文件# arm-linux-strip boa 去掉文本信息,使boa 变小# make 生成boa 文件# arm-linux-strip boa 去掉文本信息,使boa 变小5、BOA的配置BOA 需要在/etc目录下建立一个boa 目录,里面放入BOA的主要配置文件boa.conf。在BOA源码目录下已有一个示例boa.conf,可以在其基础上进行修改。 (a)、Group 的修改修改 Group nogroup 为 Grou
6、p 0 由于在/etc/group文件中没有nogroup组,所以设成0。另外在/etc/passwd 中有nobody用户,所以User nobody不用修改。(注意如果没有nobody 用户,也需要将User设成0)(b)、ScriptAlias 的修改指示CGI 脚本的存放位置。修改 ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ 为 ScriptAlias /cgi-bin/ /var/cgi-bin/ ScriptAlias /index.html /var/index.html 指示网页存放的位置。(c)、ServerName 的设置修改 Serve
7、rName ..here/ 为 ServerName ..here/ 注意:该项默认为未打开,执行BOA会异常退出,提示“gethostbyname:No such file ordirectory”,所以必须打开。其它默认设置即可。 6、BOA 的运行成功配置以后,还需要创建日志文件所在目录/var/log/boa ,创建HTML 文档的主目录/var/,将静态网页存入该目录下(可以将主机 /usr/share/doc/HTML/ 目录下的index.html 文件和img 目录复制到/var/ 目录下),创建CGI 脚本所在录 /var/cgi-bin ,将
8、cgi 的脚本存放在该目录下。另外还要将mime.types 文件复制/etc 目录下,通常可以从linux 主机的 /etc 目录下直接复制即可。实际运行时,可以将index.html文件、img目录和mime.types文件放到CF 卡目录下,建立目录后,拷贝至相应目录。制作run.sh:mkdir /etc/boacp /cf/boa/boa.conf /etc/boa/mkdir /var/logmkdir /var/log/boamkdir /var/cp /cf/boa/index.html /var/cp -r /cf/boa/img /var/mkdir /var/cgi-bi
9、ncp /cf/boa/mime.types /etc/cp /cf/boa/boa /./boa &启动浏览器,直接在浏览器中输入07/,出现BOA TEST的欢迎网页。静态HTML调试成功。1.4.2 CGI 脚本测试为了测试刚才建立的BOA服务器是否正确,我们可以编写一个简单例程进行测试。helloworld.c 程序就起这个作用,其容如下:#include<stdio.h>int main() printf("Content-type: text/htmlnn");printf("<html>n&quo
10、t;); printf("<head><title>BOA CGI TEST</title></head>n");printf("<body>n"); printf("<h1>BOA CGI TEST</h1>n");printf("</body>n");printf("</html>n");exit(0); 编写完后进行交叉编译,得到的helloworld 拷贝到var/cgi-bin
11、目录下。# arm-linux-gcc -o helloworld.cgi helloworld.c在浏览器中输入22/cgi-bin/helloworld 可以看到BOA测试页面,表示CGI 测试通过。1.5 HTML 网页设计普通的HTML 页面只能提供静态的信息给用户,如果要实现网页的交互仅靠HTML 是无能为力的。在一个完整的系统中,用户提交信息输入界面的好坏将影响到系统的成败。好的输入界面可以弥补系统设计上的某些缺陷,但如何才能设计一个好的输入界面呢?HTML 中表单(FORM)在CGI 中是常见使用的输入界面,虽然并不十分完美,但它的确是目前www中最强大的输
12、入工具。FORM是由一组相关联的标签所组成,使用方法就像HTML 中的其他标签一样。在FORM 中提供了多种输入资料的工具,如文字输入区(Text)、下拉式菜单(select)、复选框(CheckBox)、单选框(RadioButton)等等。就目前所定义的标准种,FORM 的标签可以分为<INPUT>、<SELECT>以与<TEXTAREA>三个大类。我们来看看具体的程序实现,下面是一段HTML 表单:<html><title>CGI LED test</title><body><form action
13、="/cgi-bin/cgi_led.cgi" method=GET><font size=7><center>基于S3C2440 的Web 服务器的设计程序</center></font><br><p><p><center>系统资源:s3c2440,16M Flash,32M SDRM,IP:0</center><P><center>输入要点亮的LED:<input type=text name="
14、led" ></center><br><center>输入LED 状态:<input type=text name="status" ></center><br><center><input type=submit value="确定"><input type=reset value="重设"></center></form></body></html>网页中表单由
15、字头<form>开始,</form>结束。其中action="/cgi-bin/cgi_led.cgi"指明使用的CGI 程序名为cgi_led.cgi;method 属性指定提交数据的方法(POST 还是GET),这里使用的是GET 方法。我们要实现的功能很简单,就是采集现场的LED的状态,并在网页上输出结果。在这个实例中我们提交了两个数据,一个是数据的名字是led,另一个数据的名字是status,它们的值由用户在网页中输入。这里首先了解一下CGI 编码的规则。其规则如下:不同域(变量值对)之间用“&”分开;变量与值之间用“”连接;空格符用
16、“”代替;任何特殊字符用“”接相应的十六进制ASCII 码代替,最后形成的格式为:name1=value1&name2=value2%name3=value3 .1.6 CGI 程序设计CGI(Common Gateway Interface) 通用网关接口的简称。其主要的功能是在WWW环境下,从客户端传递一些信息给WEB服务器,再由WEB服务器去启动所指定的程序来完成特定的工作。所以简单点说,CGI是一种通用的接口标准。CGI可以为我们提供许多HTML(HyperText Markup Language,超文本标记语言)无法做到的功能。比如一个计算器、顾客表格的提交以与统计、搜索引擎
17、、WEB数据库等等。用HTML是没有办法记住客户的任何信息的。要把顾客的信息记录在服务器的硬盘上,就要用到CGI。CGI是一种通用的接口标准。CGI程序就是符合这种接口标准的,运行在WEB服务器上的程序。它的工作就是控制信息要求,产生并传回所需的文件。CGI 由浏览器的输入触发这个程序。先看看浏览器浏览网页是怎样实现的。作为一个用户首先在浏览器的地址栏中添加上要访问的主页地址并回车触发这个申请。浏览器将申请发送到服务器上。WEB服务器接收这些申请并根据.htm 或.html 的后缀并认识到这是HTML 文件。WEB服务器从当前硬盘或存中读取正确的HTML 文件,然后将它送回浏览器。HTML文件
18、将被用户的浏览器解释并将结果显示在用户浏览器上。CGI程序可以用来在WEB加入动态的容。通过接口,浏览器能够发送一个可执行应用程序的请求,而不仅仅只是静态的HTML文件。服务器运行指定的应用程序,这个应用程序读取与请求相关的信息,获得请求传过来的数值。例如使用者填写HTML表单提交了数据,浏览器将这些数据发送到WEB服务器上。WEB服务器接收这些数据并根据客户机指定的CGI程序把这些数据递交给指定的CGI程序,并使CGI在服务器上运行。CGI程序运行结束,生成HTML页面,WEB服务器把CGI程序运行的结果送回用户浏览器。HTML文件将会被用户的浏览器解释并将结果显示在用户浏览器上。CGI的基
19、本工作情况如下图所示:图3.3 CGI工作流程示意图WEB服务器与CGI 程序之间通过四种途径进行通信:环境变量、命令行、标准输入和标准输出。其中负责输入的有环境变量、命令行和标准输入。命令行只用于ISINDEX 查询,较少使用。环境变量存放服务器向CGI程序传递的一些运行参数, 比如REQUEST_METHOD表示用户提出请求或提交数据的方法是GET 还是POST。方法(METHOD) 是中对命令的称呼。GET方法通过环境变量QUERY-STRING传递用户提交的数据。经过编码的数据以问号打头追加在标识CGI脚本地址的URL后一起传给WEB服务器。服务器将其存于QUERYSTRING中,CG
20、I 程序可以通过getenv( )函数来读取。编码数据除了表单数据,还可以是直接调用CGI脚本时追加在URL 地址后面的参数。POST 方法则通过标准输入( stdin) 传递提交数据。编码了的表单数据独立地传送给WEB服务器, CGI 程序从标准输入中获得,可以用getchar( ), sscanf( ) , fread( ) 等函数。要注意的是数据的长度是通过读取环境变量CONTENT_LENGTH 获得的,而不是通过文件尾标识符来判断。一般而言,要使用CGI 程序就必须在WEB网页中迁入调用CGI 程序的代码。通常的做法有三种,一是通过表单调用,二是通过超调用,三是通过SSI 调用。在3
21、.5节中我们已经阐述了网页的设计,在这里重点说明使用表单调用CGI 程序的办法。 我们来看看到底如何从GET表单收集数据到CGI 程序,下面给出了一个比较简单的C 源代码:#include <stdio.h> #include <stdlib.h> #include <sys/ioctl.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/mman.h>
22、; #define DEVICE_GPIODRV "/dev/gpios"int main() int fd; int led; int status; char *data; if(fd=open(DEVICE_GPIODRV,O_RDONLY | O_NONBLOCK)<0) printf("open device: %sn",DEVICE_GPIODRV); perror("can not open device"); exit(1); printf("Content-type:ext/html;charset=
23、gb2312nn");printf("<html>n"); printf("<head><title>CGI LED DEMO</title></head>n"); printf("<body>n"); printf("<h1>CGI LED DEMO 1:0 led1 on 1:1 led1 off</h1>n"); printf("</body>n"); data=geten
24、v("QUERY_STRING"); if(sscanf(data,"led=%ld&status=%ld",&led,&status)!=2) printf("<p> 请正确输入"); printf("</p>"); if(led>3) printf("<p>Please input 0<=led<=3!"); printf("</p>"); if(status>1) print
25、f("<p>Please input 0<=status<=1!"); printf("</p>"); ioctl(fd,status,led); close(fd); printf("</html>n"); exit(0); 对于CGI程序来讲,当采用GET方式提交数据时,用户提交的数据放在环境变量QUERY_STRING中。CGI程序从环境变量QUERY_STRING获得数据。为了解释和执行程序,CGI必须要分析(处理)这个字符串。当你想从服务器获得数据并且不改变服务器上的数据时,应
26、该选用GET。但是用GET 方式提交时,数据不经过CGI编码,而且数据长度不能超过1K字节。否则只能用POST方式了。CGI 程序的任务大概有两部分,输入任务和输出任务。输入任务就是指获取用户提交数据的过程。输入任务大概分以下几个步骤:(1)首先从CGI 环境变量REQUESR_METHOD中获取CGI程序的提交方式;(2)根据提交方式的不同取出变量名和变量值。如果是Get方式,从环境变量QUERY_STRING 中取出编码数据;如果是POST 方式,从标准输入输出中读取相应的字符串,读取长度有环境变量CONTENT_LENGTH 决定。(3)根据CGI 编码规则取出字符串中的数据(变量名和变
27、量值对)。在输入任务完成后,我们得到所有的变量名和变量值对,而后就是输出任务。输出任务主要有三个:(1)输出响应的头标志。如printf(“Content-type:ext/htmlnn”);它告诉Web 服务器随后的输出是以HTML 文本形式输出的。注意这个头信息中有两个换行符,这是因为WEB服务器需要在实际的文本信息开始之前先看见一个空行。(2)调用其它程序(如远的测量程序、设置参数的程序、或者查询数据库的程序)。(3)输出CGI 程序执行结果。表单提交数据测试了解了POST 和GET 两种表单提交数据方式以与步骤后,下面进行测试。GET方式:对于那些使用了属性“METHOD=GET”的表
28、单(或者没有METHOD 属性,这时候GET 是其缺省值),CGI 定义为:当表单被发送到服务器端后,表单中的数据被保存在服务器上一个叫做QUERY_STRING的环境变量中。这种表单的处理相对简单,只要读取环境变量就可以了。这一点对不同的语言有不同的做法。在C语言中,你可以用库函数getenv(定义在标准库函数stdlib中)来把环境变量的值作为一个字符串来存取。你可以在取得了字符串中的数据后,运用一些小技巧进行类型的转换,这都是比较简单的了。在CGI 程序中的标准输出(output)(比如在C中的stdout文件流)也是经过重定义了的。它并没有在服务器上产生任何的输出容,而是被重定向到客户
29、浏览器。这样,如果编写一个C 的CGI 程序的时候,把一个HTML 文档输出到它的stdout 上,这个HTML 文档会被在客户端的浏览器中显示出来。这也是CGI 程序的一个基本原理。上例中具体的C 语法就不多讲了,我们来看看它作为CGI 程序所特殊的地方。前面已经提到标准输出的容就是要被显示在浏览器中的容。第一行的输出容是必须的,也是一个CGI 程序所特有的:printf("Content-type: ext/html;charset=gb2312nn"),这个输出是作为HTML 的文件头。因为CGI 不仅可以像浏览器输出HTML 文本,而且可以输出图像,声音之类的东西。
30、这一行告诉浏览器如何处理接受到的容。在Content-Type 的定义后面跟有两行的空行,这也是不可缺少的。因为所有CGI 程序的头部输出都是相近的,因而可以为其定义一个函数,来节省编程的时间。这是CGI 编程常用的一个技巧。程序在后面调用了用了库函数getevn 来得到QUERY_STRING 的容,然后使用sscanf 函数把每个参数值取出来,要注意的是sscanf 函数的用法。其他的就没有什么了,和一般的C 程序没有区别。把程序编译后,改名为cgi_led.cgi 放在/cgi-bin/目录下面,就可以被表单调用了。这样,一个处理GET 方式表单的CGI 程序就大功告成了。POST方式:
31、下面我们来考虑另外一种表单传送方法。假设我们要实现的任务是这样的:把表单中客户输入的一段文本容添加到服务器上的一个文本文件的后面。这可以看作是一个留言版程序的雏形。显然,这个工作是无法用java script 这种客户端脚本来实现,也算得上真正意义上的CGI 程序了。看起来这个问题和上面讲的容很相近,仅仅是用不同的表单和不同的脚本(程序)而已。但实际上,这中间是有一些区别的。在上面的例子中,GET 的处理方法可以看作是“纯查询(purequery)”类型的,也就是说,它与状态无关。同样的数据可以被提交任意的次数,而不会引起任何的问题(除了服务器的一些小小的开销)。但是现在的任务就不同了,至少它
32、要改变一个文件的容。因而,可以说它是与状态有关的。这也算是POST 和GET 的区别之一。而且,GET 对于表单的长度是有限制的,而POST 则不然,这也是在这个任务中选用POST 方法的主要原因。但相对的,对GET 的处理速度就要比POST 快一些。在CGI 的定义中,对于POST 类型的表单,其容被送到CGI 程序的标准输入(在C 语言中是stdin),而被传送的长度被放在环境变量CONTENT_LENGTH 中。因而我们要做的就是,在标准输入中读入CONTENT_LENGTH 长度的字符串。从标准输出读入数据听起来似乎要比从环境变量中读数据来的要容易一些,其实则不然,有一些细节地方要注意
33、,这在下面的程序中可以看到。特别要注意的一点就是:CGI 程序和一般的程序有所不同,一般的程序在读完了一个文件流的容之后,会得到一个EOF 的标志。但在CGI 程序的表单处理过程中,EOF 是永远不会出现的,所以千万不要读多于CONTENT_LENGTH 长度的字符,否这会有什么后果,谁也不知道(CGI 规中没有定义,一般根据服务器不同而有不同得处理方法)。我们来看看到底如何从POST 表单收集数据到CGI 程序,下面给出了一个比较简单的C 源代码。#include<stdio.h> #define MAXLEN 80 #define EXTRA 5 /* 4 个字节留给字段的名字
34、"data", 1 个字节留给"=" */ #define MAXINPUT MAXLEN+EXTRA+2 /* 1 个字节留给换行符,还有一个留给后面的NULL */ #define DATAFILE "data.txt" /* 要被添加数据的文件 */ void unencode(char *src, char *last, char *dest) for(; src != last; src+, dest+) if(*src = "+") *dest = " " else if(*src
35、= "%") int code; if(sscanf(src+1, "%2x", &code) != 1) code = "?" *dest = code; src +=2; else *dest = *src; *dest = " " *+dest = "" int main(void) char *lenstr;char inputMAXINPUT, dataMAXINPUT;long len; FILE *f;printf("Content-type: text/html
36、;charset=gb2312nn");printf("<html>n"); printf("<head><title>Response</title></head>n");printf("<body>n"); printf("<h1>Response</h1>n");printf("</body>n");lenstr = getenv("CONTENT_LENGTH&
37、quot;);if(lenstr = NULL | sscanf(lenstr,"%ld",&len)!=1 | len > MAXLEN) printf("<p>表单提交错误"); printf("</p>"); else fgets(input, len+1, stdin);unencode(input+EXTRA, input+len, data);f = fopen(DATAFILE, "a");if(f = NULL)printf("<p>对不起
38、,意外错误,不能够保存你的数据 "); printf("</p>"); else fputs(data, f); fclose(f); printf("<p>非常感,您的数据已经被保存<br>%s",data); printf("</p>"); printf("</html>n"); exit(0); 从本质上来看,程序先从CONTENT_LENGTH 环境变量中得到数据的字长,然后读取相应长度的字符串。因为数据容在传输的过程中是经过了编码的,所
39、以必须进行相应的解码。编码的规则很简单,主要的有这几条:1、表单中每个每个字段用字段名后跟等号,再接上上这个字段的值来表示,每个字段之间的容用&连结;2、所有的空格符号用加号代替,所以在编码码段中出现空格是非法的;3、特殊的字符比如标点符号,和一些有特定意义的字符如“+”,用百分号后跟其对应的ACSII 码值来表示。例如:如果用户输入的是:Hello there!那么数据传送到服务器的时候经过编码,就变成了data=Hello+there%21 上面的unencode()函数就是用来把编码后的数据进行解码的。在解码完成后,数据被添加到data.txt 文件的尾部,并在浏览其中回显出来。
40、把文件编译完成后,把它改名为collect.cgi 后放在CGI 目录中就可以被表单调用了。下面给出了其相应的表单:<html> <title>CGI POST test</title> <body> <h1>CGI POST test<h1><br> <form method="post" action="cgi-bin/collect.cgi"> <P>请输入您的留言(最多80 个字符):<br><input NAME=&qu
41、ot;data" SIZE="60" MAXLENGTH="80" ><br > <input type=submit value="确认"> </form> </body> </html> 事实上,这个程序只能作为例子,是不能够正式的使用的。它漏掉了很关键的一个问题:当有多个用户同时像文件写入数据是,肯定会有错误发生。而对于一个这样的程序而言,文件被同时写入的几率是很大的。因此,在比较正式的留言版程序中,都需要做一些更多的考虑,比如加入一个信号量,或者是借助
42、于一个钥匙文件等。因为那只是编程的技巧问题,在这儿就不多说了。最后,我们来写一个浏览data.txt 文件的的CGI 程序,这只需要把容输出到stdout 就可以了: #include < stdio.h > #include < stdlib.h > #define DATAFILE "./data/data.txt" int main(void) FILE *f = fopen(DATAFILE,"r"); int ch; if(f = NULL) printf("%s%c%c ", "Conte
43、nt-Type:text/html;charset=gb2312",13,10); printf("< TITLE >错误 < /TITLE > "); printf("< P >< EM >意外错误,无法打开文件< /EM >"); else printf("%s%c%c ", "Content-Type:text/plain",13,10); while(ch=getc(f) != EOF) putchar(ch); fclose(f); r
44、eturn 0; 这个程序唯一要注意的是:它并没有把data.txt 包装成HTML 格式后再输出,而是直接作为简单文本(plain text)输出,这只要在输出的头部用text/plain 类型代替text/html 就可以了,浏览器会根据Content-Type 的类型自动的选择相应的处理方法。1.7 设备驱动程序设计现在设计一个简单的LED 控制页面。当输入1 /0时对应的LED灯亮灭。LED 驱动程序使用insmod命令加载,CGI 程序编译后放在var/cgi-bin 目录下。#include <linux/config.h> #include <linux/mod
45、ule.h>#include <linux/kernel.h>#include <linux/fs.h> #include <linux/init.h>#include <linux/devfs_fs_kernel.h> #include <linux/miscdevice.h> #include <linux/delay.h> #include <asm/irq.h> #include <asm/arch/regs-gpio.h> #include <asm/hardware.h>
46、;#define DEVICE_NAME "gpios"#define GPIO_MAJOR 215static unsigned long gpio_table = S3C2410_GPD0, S3C2410_GPD1, S3C2410_GPD2, S3C2410_GPD3, ; static unsigned int gpio_cfg_table = S3C2410_GPD0_OUTP, S3C2410_GPD1_OUTP, S3C2410_GPD2_OUTP, S3C2410_GPD3_OUTP, ; static int sbc2440_gpios_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) switch(cmd) case 0: case 1:
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论