已阅读5页,还剩15页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
本 科 毕 业 论 文题 目: 基于lwip的嵌入式网络终 端设计 目 录摘 要4abstract51引言61.1 研究背景61.2 本科生研究的意义72基于lwip的嵌入式网络终端的总体结构82.1嵌入式网络终端的整体设计82.2硬件设计82.2.1 stm32f107概述82.2.2 stm32f107的以太网功能描述82.2.3 smi站管理接口92.2.4 smi写操作102.2.5 smi的读操作102.3 tcp/ip的实现和设计112.3.1 tcp/ip协议的体系结构112.3.2 ip协议概要及ip处理122.3.3 tcp处理132.3.4 api的实现13lwip设计153.1 lwip与应用程序153.2 lwip与底层网络154总结与展望17致谢18参考文献19附件20摘 要因特网的快速发展和成熟,3c(计算机,通讯,消费电子)合一为主流的数字时代已经到来,电冰箱,空调等电器也不再功能单一,电器结构也变得更加复杂,更加人性化。互联网已经达到在全球范围内的连通性,网络通信也成了人们购买产品中考虑的一种选择性条件。而一些小型轻便的设备,处理能力不强,内存资源有限,需要在这类产品上实现联网通信就成了现今比较热的话题。而lwip正式为解决这类问题提出的一种解决方案。lwip是tcp/ip协议栈的一种实现,lwip的主要目的是减少内存使用率和代码尺寸,使得lwip适用于资源有限的处理器,如嵌入式系统。为了简化处理过程和内存的要求,lwip对api进行了裁剪,可以不需要复制一些数据。本文介绍了在stm32f107上实现基于lwip的web服务器,客户端可以通过访问服务器对网络终端进行控制。为了使用户能够通过互联网对嵌入式设备进行实时控制,嵌入式web服务器的设计符合了嵌入式设备和网络技术的发展要求。因为作为本科生的毕业设计,所以本文设计的系统以功能性作为首要的考虑问题,并在此基础上最大程度的降低成本。本文主要描述lwip的设计和实现,并在此基础上实现嵌入式web服务器的通讯应用。叙述了stm32f107的硬件结构,以太网功能,以及lwip在tcp/ip协议栈的实现中的操作系统,应用程序,底层网络中使用的数据结构和算法。关键词: stm32f107,嵌入式,lwip,web服务器abstractthe rapid developmentofinternetand3c(computer,communications,consumer electronics)oneofthe mainstreamof the digital agehas come,refrigerators, air-conditionersandother electrical appliancesare no longersingle function,theelectricalstructurebecomes more complex,more humane.theinternethas reachedworldwideconnectivity,network traffichas becomethepeople to buyproductsto considera selectiveconditions.some smallportabledevices,theprocessing capacityi-snot strong, limitedmemory resources,networking and communicationson these productshas becometodayshottopic.lwipis a solution to formallyproposedt-osolve such problems.lwipisan implementationoftcp/ip protocolstack,implementation of lwipsmain purpose istoreducememory usageand codesize,makelwipapply tolimited resources,processor, such asembedded systems. in order to simplifytheprocessingandmemory requirements, lwipapicutting,donotneedtocopy somedata. this article describesinstm32f107-basedlwipweb server,the clientcanaccess the serveron the networkterminalcontrol. in order toenable users toembedded devices,real-time controlvia the internet,theembeddedwebserverdesigned to meettherequirementsofembedded devicesand thedevelopment of network tec-hnology. undergraduategraduationdesign, sothis paper, the design of thesyste-mto be functionalasaprimary consideration,andon this basis,the greatest degree oflower costs. this paper describes thedesignand realizationoflwipembedded web servercommunicationapplications,andon this basis.describedthest-m32f107ofhardwarestructure, theethernetfunction,aswellaslwipintheimple-mentationofthetcp / ip protocolstack,o-perating system,application,usedinth-eunderlying networkdata structuresand algorithms. thetest results show thatth-eperformanceof the systemcould meet thedesign requirements.key words: stm32f107,embedded, lwip,web server1 引言近几年来,随着科学技术日新月异的发展,计算机科技的快速发展,特别是互联网的快速普及,互联网在人类活动中也越来越紧密联系,尤其是对于工业控制和信息电器领域中同样有着越来越重要的应用。同时计算机,通讯,消费电子三合一的快速发展,数字化时代已经到来。而嵌入式接入设备是数字化时代的一大主流标志,形态各异的计算机,通讯,消费电子三合一产品也将是网络接入设备的一大主流。因为pc机以及现有的internet技术可以实现对非网络设备进行远程控制的部分的要求,而且成本费用较高,可靠性和期望值也有一定的距离,所以这种方案并没有被广泛的接受和使用。由于嵌入式设备具有低成本高性能的特点,而现今对嵌入式系统的开发研究和嵌入式技术也都进入到了一个成熟的阶段,将嵌入式系统和网络相结合来实现非网络系统的网络控制,那么世界可能就是另一番景象。 1.1 研究背景因特网技术的成熟,使得网上提供的信息更加丰富,应用项目也更加多样,人们对网络的需求也越来越广泛,利用pc机上网来查阅和发布各类信息等对于网络的日常应用已经不能满足人们的需求。像传统的电器,电冰箱,微波炉,电视,空调等,这类电子设备的功能也不在单一,电器结构也更为复杂,也逐步开始应用嵌入式网络接入,使用户可以通过网络就能实现远程控制,信息通讯。同样,互联网在全球范围内的连通性,那些能够连接因特网的设备也成为人们选择产品中考虑的一大问题,通过internet对家用电器等非网络设备进行远程控制已经成为现今主流。而一些小型轻便的设备,比如一些医学仪器上的身体上使用的传感器,体积小而且便宜,内存小,运算能力有限,因此必须在资源受限的情况下实现tcp/ip协议甚至处理接受到的信息。tcp/ip协议可以分为四个层次,从底层到最高层分别是物理层和数据链路层,网络层,传输层,和最高层的应用层。物理层和数据链路层是tcp/ip协议的最低层,要求提供给上层一个访问接口,以便传递ip分组信息。网络层是第二层,也是整个tcp/ip协议栈的核心,其功能是把分组发往目标网络或主机,源主机与目的主机可以在同一个网上,也可以在不同的网上。其中定义了分组格式和协议,即ip协议,来对分组进行排序。ip协议是一种不可靠、无连接的数据报发传送服务的协议,提供的只是一种尽力而为的服务。传输层是第三层,负责在应用进程中的端到端之间的通信。传输层定义了两种服务质量不同的协议,tcp和udp。tcp是一种可靠的面向连接的协议,允许将源主机的字节数据流无差别的传送到目的主机。同时能够完成流量的控制功能,协调收发主机之间的发送和接受速度,从而控制正确的传输。应用层是最高层,其中也包括了很多协议:文件传送协议,简单邮件传送协议,简单网络管理协议,超文本传送协议等。lwip是瑞士计算机科学院一个开源的tcp/ip协议栈实现。lwip是light weight ip协议,有无操作系统都可以运行,其实现的重点是在保持tcp/ip协议的主要功能的基础上减少对内存的占用,一般只需要几百字节的ram和40k左右的rom就可以运行,这使得lwip成为在资源受限的情况下实现及处理tcp/ip协议的解决方法。lwip可以支持多网络接口下的ip转发,提供专门的内部回调接口raw api,这样可以提高应用程序性能。像lwip的目标系统是最小限度系统,所使用的操作系统通常不能在内核与应用层进程之间维持一个严格的保护屏障。这里允许使用一种比较宽松的通许机制,通过共享内存的方式实现应用层与底层协议族之间的通讯。应用层可以知道底层协议使用的缓冲处理机制,这使得应用层可以有效的重复使用缓冲区。同样,应用层与网络代码使用的是相同的内存区,那么应用层就可以直接读写内部缓冲区。1.2 本科生研究的意义作为一个本科生,试着去了解一下这门新兴的、紧密连接着数字时代前沿的学科是很有必要的,同时,也可以以此作为契机来检验自己在大学四年里所学的理论知识,并将其应用到实践中,理论和实践相结合,而且嵌入式作为一门新兴的技术,基于lwip的嵌入式网络终端设计也是一个很好的毕业设计的题目。stm32f107中以太网mac(medium access control介质访问控制)构成数据链接路层,外部phy构成了物理层,lwip构成网络层以及传输层。操纵系统与lwip的接口是lwip的操作系统模拟层。lwip依靠操作系统来实现线程,信号量,邮箱和队列等以及那些与这些相关的操作,同时,考虑到我们实验室有stm32f107,所以,本文就采用stm32f107硬件条件下基于lwip的嵌入式网络终端设计,在stm32f107上实现基于lwip的web服务器,客户端可以通过访问服务器对网络中断进行控制以及信号的一些简单的数据处理。2 基于lwip的嵌入式网络终端的总体结构2.1嵌入式网络终端的整体设计 嵌入式网络终端的设计分为两部分硬件设计和软件设计。硬件设计是建立在stm32f107的开发板和一个外部的phy(物理接口收发器)这个组合上的。它为实现嵌入式网络终端设计的tcp/ip协议上的提供数据链路层和物理层。软件设计上,主要是依靠lwip来实现,lwip在功能上实现tcp/ip协议上的网络层和传输层。而操纵系统和lwip的接口就成为了lwip的操作系统模拟层,从而实现了tcp/ip协议的应用层功能。根据嵌入式网络终端和tcpip协议栈的设计和实现的功能上将本次毕业设计分成以下几个部分:1、 硬件上stm32f107和外部的物理接口收发器实现tcp/ip协议的数据链路层和物理层。2、 lwip的实现tcpip协议的网络层和传输层,即lwip在操作系统上的移植。3、 lwip实现过程中的操作系统模拟层实现,缓冲和内存管理的子系统,网络接口函数实现。2.2硬件设计2.2.1 stm32f107概述 32位arm cortex-m3结构,72mhz运行频率,1.25 dmips/mhz,硬件除法和单周期乘法,并可快速可嵌套中断,612个时钟周期,有64k256kb的flash,以及高达64kb的sram。另外在网络通信功能上,具有一个rj45网络接口,支持10m/100m自适应网络,还有一个zigbee无线网络通讯接口,一个wi-fi wlan无线宽带网络通讯接口。在本开发板上,添加了一些人机交互接口,一个大屏幕320*240,262144色tft-lcd,支持spi接口式/总线接口,四个led发光管,一个电源led指示灯,另外一个标准3.5mm耳机接口,一个五方向的输入摇杆,3个gpio按键,1个reste按键,以及音频级处理芯片,usb otg功能能,支持外接鼠标和键盘。串行通信功能上,有两个rs232连接插座,其中一个rs232带硬件流控制引脚,一个mini型usb插座,两个can连接口。其中与以太网最重要的硬件是mac(介质访问控制)及其专用的dma。专用的dma控制器允许专用sram和描述符之间高速传输,其中一些地址过滤模式,对物理和组发送地址,以及32位状态编码,用于每个传送和接受帧。内部的fifo用于缓存传输和接受帧,传输fifo和接受fifo都是2kbyte,总共4kbytes。2.2.2 stm32f107的以太网功能描述stm32f107支持两种工业标准的物理层接口,默认的介质无关接口mii和精简的介质无关接口rmii。以太网的外设由mac和一个专用的dma控制器,支持默认的mii和rmii通过一个选择位来设置默认的mii接口或者精简mii接口。tdma控制器接口通过ahb主从接口连接核和内存,ahb主接口控制数据传输当ahn从接口访问控制盒状态寄存器空间。在mac核传输前,传输fifo缓存通过dma从系统内存中读取数据,类似的,接受的fifo队列从线上储存以太网帧从而知道它们被dma传送到了系统内存中。以太网的外设还包括一个smi用于和外部的phy通信。配置寄存器允许用户为mac和dma控制器选择想要的模式和特性。图2-1 stm32f107以太网原理框图2.2.3 smi站管理接口smi(station management interface 站管理接口)允许应用程序通过一根时钟数据线来读取配置中任意一个物理寄存器,接口最多支持访问是32个phy。应用程序可以在smi的允许下选择32个phy中的其中一个,再在phy中32个寄存器中的任意一个来发送控制数据或者接受状态信息。但是在给定的时间里,只能访问一个phy中的寄存器。如图2-1所示,图中微控制器执行使mdc时钟线和mdio数据线来为交替的功能i/o扣。mdc是一个用于给数据传输提供时间参考的周期性时钟,最大的频率为2.5mhz,最小的mdc的高低时间是每次160ns,最小的周期是400ns。值得注意的是,在不工作的情况下,smi管理接口驱动mdc时钟信号为低,即为0。而mdio是数据输入和输出数据是要用mdc时钟信号来同步传输状态信号给物理设备,或者从物理设备那得到状态信号。stm32macexternalphymdiomdc图2-2 smi管理接口框图2.2.4 smi写操作当应用程序设置介质无关接口mii写和忙位时,smi通过传输phy的地址,phy中的寄存器地址以及写数据来启动一个写操作到phy寄存器上。当然,在传输过程中应用程序不能改变mii的地址寄存器中的内存或者是mii数据寄存器。在这个写操作的时间里,任何对mii地址寄存器和mii数据寄存器的写操作都会被忽略(忙时位为高,即为1),保证传输过程无差错完成。这个写操作完成之后,smi又通过复位忙位,使得可以重新接受新的写操作。图2-3 smi写操作2.2.5 smi的读操作用户设置以太网mac中mii的地址寄存器中的mii busy bit时,mii write bit 为零,smi就通过传输phy地址和phy中的寄存器的地址,然后在phy寄存器中就启动一个读操作。同样的,在传输过程中应用程序不能改变mii地址寄存器中的内容或者mii数据寄存器中的内容。同时在读操作过程中,对mii地址寄存器和mii数据寄存器的写操作也会被忽略(busy bit为高,即为1),保证传输过程不差错,能够正确完成。读操作完成后,smi复位busy bit,然后用从phy中读到的数据来更新mii数据寄存器。图2-4 smi读操作2.3 tcp/ip的实现和设计2.3.1 tcp/ip协议的体系结构图2-5 tcp/ip协议各层关系应用程序使用tcp传送数据时,数据被送入协议栈中,逐步通过每一层,最后直到被当做一串比特流送入到网络当中。每层对于收到的数据都要在数据首部加些信息,tcp传给ip的数据单元称为tcp报文段。ip传给网络层的数据单元称作ip数据报。数据帧是由帧头、ip数据包和帧尾构成的,帧头包括源主机和目标主机的mac地址以及类型,帧尾是校验字。ip数据包又是有ip头部和tcp数据信息组成的。ip头包括源主机和目标主机的ip地址、类型等。tcp数据信息就是tcp头部和真正的实际数据。tcp头包括源主机和目标主机的端口号、顺序号、确认好、校验字等。2.3.2 ip协议概要及ip处理ip是tcpip协议族中最为重要最为核心的协议,所有的tcp、udp、icmp及igmp数据都以ip数据报格式传输。如同一辆运货的卡车,需要将一车一车的货物运向目的地,主要的货物就是tpc活着udp分配给它的。ip提供不可靠、无连接的数据报传送服务,它不能保证ip数据报能够成功地到达目的地。ip仅仅提供最好的传输服务,但是不保证ip数据报能够成功地到达目的地。如果该过程中发生某种错误时,如网络系统中某个路由器暂时用完了缓冲区,ip有一个简单的错误的处理算法:丢弃该数据报,然后发送icmp消息给信源端。图2-6 ip数据报格式及首部中的各字段普通ip首部长为20个字节,除非含选项字段。如图2-3-2所示,最高位在左边,记0bit;最低位在右边,记31bit。4个字节的32bit值下面的次序传输:首先是17bit,其次815bit,然后1623bit,最后2431bit。这种传输次序称作bigendian字节序,也称作网络字节序。对于处理ip信息包,由网络设备驱动调用函数ip_input()处理,完成对ip版本字段及包头长度的初始检查,还要同时计算和验证包头校验和。接下来,函数检查目的地址是否与网络接口的ip地址相符合以便确定信息包是否已到达预定的目的地。网络接口在链表中被排序并且采用了线性检索。如果一个到达的信息包被检查到已经到达了目的地(目的主机),则由协议字段来决定信息包应该传送到哪个上层协议。外发的信息包由ip_output()函数处理,查找到适当的网络接口来传送信息包,当外发的网络接口被确定后,信息包传给以外发网络接口为参数的ip_output_if()函数。此时,所有的ip包头字段被填充,并同时计算ip包头的校验和。将ip信息包的源以及目标地址作为参数传递给ip_output_if()函数。通过线性检索网络接口链表找到适当的网络接口,因为在检索期间,网络接口的网络掩码会对ip信息包的目标地址进行掩码运算,经掩码运算过后的目标地址等于同样经过掩码运算的接口ip地址,则找到正确合适的网络接口,即选择这个接口。2.3.3 tcp处理tcp属于传输层协议,为应用层提供可靠的字节流服务。将tcp处理过程分割为六个功能函数来实现:tcp_input()、tcp_process()及tcp_receive()函数用于tcp输入,tcp_write()、tcp_enqueue()及tcp_output()则用于tcp输出。发送过程的发起者是应用层,调用ip_write()函数,接着其再将控制权交给tcp_enqueue()函数,这个过程后,数据会被分割成适当大小的tcp段,然后这些tcp段会被放到所属连接的传输队列中。此时,tcp_output()函数会检查现在是不是符合条件发送数据,判断接收器窗口是否拥有足够大的空间,阻塞窗口是否也足够大,条件满足时,ip_route()和ip_output_if()函数就会发送数据。接收过程中的发起者是网络层,网络层将数据包传递给ip_input()函数,验证ip版头后移交给tcp段给tcp_input()函数,由其校验和验证与tcp选项解析,并判定这个tcp段属于哪个tcp连接。然后tcp段到tcp_process()函数,实现必要的状态转换,调用tcp_receive()函数,并将数据传给上层的应用程序。若这个tcp段包含的信息是不被承认的ack应答数据构成,数据就会从缓冲区移走,如果收到的是一个ack应该确认数据,接收器就会同意接受更多的数据,tcp_output()函数就会被调用。2.3.4 api的实现程序的执行使靠回调函数来驱动的,每一个回调函数也只不过是一个能够直接被tcp/ip代码调用的普通的c语言函数,每一个回调函数的调用也都是传递一个当前连接udp或者tcp的状态。建立tcp连接函数:建立连接函数同sequential api很相似,一个新的tcp连接的标志由tcp_new()函数来创建,其实质上就是一个协议控制块-pcb的创建。连接创建后,新建的协议控制块就进入监听状态,等待数据接收的连接信号,也可以是直接连接到另外的一个主机上。tcp_new():定义一个tcp_pcb控制块后首先被调用,建立该控制块的连接标志。其原型是struct tcp_pcb *tcp_new(void),正常建立连接标志后返回建立的pcb。tcp_bind():用于绑定本地的ip地址和端口号,用户可以将其绑定在一个任意的本地ip地址上,它也只能在函数tcp_new()调用之后才能调用。它的原型是err_t tcp_bind(struct tcp_pcb *pcb,struct ip_addr *ipaddr,u16_t port),正确绑定了制定连接时返回ok。ipaddr绑定的是ip地址,port绑定的是本地的端口号。tcp_accept():当处于监听的连接与一个新来的连接连接上后,该函数指定的回调函数将会被调用。通常在tcp_listen()函数调用之后调用。其原型为:void tcp_accept(struct tcp_pcb *pcb,err_t(*accept)(void *arg,struct tcp_pcb *newpcb,err_t err);tcp_listen():当一个正在请求的连接被接收时,由tcp_accept()函数制定的回调函数将会被调用。调用本函数前,必须首先调用函数tcp_bind()来绑定一个本地的ip地址和端口号。原型是:struct tcp_pcb *tcp_listen(struct tcp_pcb *pcb),pcb指将要进去监听状态的连接。tcp_listen_with_backlog():该函数用于限制在监听队列中未处理的连接数量,通过参数backlog来实现。tcp_connect():请求参数pcb指定的连接连接到远程主机,并发送打开连接最初的syn段,函数tcp_connect()调用后立即返回,并不等待连接一定要正确建立。如果正确建立,它可以直接调用第四个参数指定的函数(connected参数)。相反,连接未正确建立,其原因可能是远程主机拒绝连接,或者远程主机不应答,此时都会调用connected函数来设置相应的参数err。其原型:err_t tcp_connect(struct tcp_pcb *pcb,struct ip_addr *ipaddr,u16_t port,err_t (*connected)(void *arg,struct tcp_pcb *tpcb,err_t err); lwip设计3.1 lwip与应用程序接收到的数据暂存在分开的较小的内存块中,但是许多应用程序都需要在一块连续的内存区域内处理数据,因此就需要一个专门的函数来负责从这些不连续的缓冲区内复制数据到一个连续的内存区。lwip的进程模型:所有的tcp/ip协议独立于操作系统内核之外,驻留在同一个进程的方式,tcp/ip协议栈和操作系统内核分开了,应用层程序既可以是单独的进程也可以是驻留在lwip的进程中。应用程序与lwip协议栈一般使用两种方式通信,而如上述所说的,应用程序驻留在lwip的进程中时,一般是采用函数调用的方式,而另一种是使用api。3.2 lwip与底层网络设备驱动是底层硬件和整个软件部分的接口,需要对外部的phy进行控制,尤其是寄存器的配置,来实现数据的发送和接收,并为上层协议提供访问的方法。主要的工作包括初始化,设备的打开和关闭,数据包的发送和接收,中断处理等。而其中lwip提供了一些网络驱动的模型。使用lwip提供的api做一些网络驱动时,需要对lwip协议栈进行初始化,用一个网络接口的初始化函数来完成底层网络的初始化功能做,添加并配置底层网络接口,建立底层的接收或发送线程,创建tcp/ip线程等。lwip的底层接口初始化其实就是对数据链路层和物理层功能的实现。需要做几个方面的动作:lwip的初始化、网络层设备的初始化、以太网控制器的初始化等。如图3-1所示,网络模块的初始化函数的流程是首先是lwip协议栈的初始化,再进行数据链路层发送接收线程的创建,之后进行网络层设备的初始化。图3-1 lwip底层接口初始化而进行lwip协议栈初始化时,先初始化lwip统计信息,初始化操作系统的仿真层,再进行初始化存储管理结构,最后创建tcp/ip线程。lwip协议栈的初始化中可以调用lwip协议栈所提供的api来实现。以太网控制器的初始化中,对于stm32f107,需要在初始化中进行设定网卡的mac地址,初始化网卡,建立稳定的物理层和数据链路层。然后开始向lwip注册链路层发送函数,创建接受线程。而网卡初始化过程中需要进行几个步骤:1、 关闭fec模块2、 关闭中断3、 注册中断向量和中断处理函数4、 开启中断5、 设置mac地址和flash寄存器6、 设置发送控制寄存器和接收控制寄存器7、 初始化发送函数和接收函数8、 开启fec模块在硬件模块完成了物理层和数据链路层的构建,这时,需要一方面从mac中提取数据部分,然后传送给lwip协议栈线程进行处理,一方面要把上层中的ip数据包传送给硬件模块,通过硬件模块把数据封装成mac帧发送到物理网络上。这个过程中为了减少中断处理程序的反复使用,可以将底层数据到lwip协议栈的数据传送工作独立出来,独立出一个接收线程和一个发送线程来完成。接收线程和发送线程与底层驱动中数据收发的同步可以利用信号量的机制来实现。4 总结与展望lwip是tcp/ip协议栈的一种实现,lwip的主要目的是减少内存使用率和代码尺寸,使得lwip适用于资源有限的处理器,如嵌入式系统。为了简化处理过程和内存的要求,lwip对api进行了裁剪,可以不需要复制一些数据。在stm32f107上实现基于lwip的web服务器,客户端可以通过访问服务器对网络终端进行控制。为了使用户能够通过互联网对嵌入式设备
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论