模拟Ethernet帧的发送过程.doc_第1页
模拟Ethernet帧的发送过程.doc_第2页
模拟Ethernet帧的发送过程.doc_第3页
模拟Ethernet帧的发送过程.doc_第4页
模拟Ethernet帧的发送过程.doc_第5页
免费预览已结束,剩余22页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

武汉理工大学计算机网络课程设计说明书目 录1.设计题目与要求21.1 设计题目21.2设计要求21.2.1 初始条件:21.2.2 具体要求22. 总的设计思想及系统平台、语言、工具等32.1理论学习32.1.1 Ethernet帧的发送过程32.1.2 Ethernet帧接收流程32.2 总的设计思想32.3系统平台、语言、工具43 数据结构与模块说明(功能与流程图)43.1 详细设计43.2 数据结构53.2.1 主程序调用53.2.2 无冲突模块53.2.3 有冲突模块63.2.4 截止二进制指数后退算法63.3.算法流程图:73.3.1主程序73.3.2 Ethernet类流程图73.3.3线程A,B的流程图:84程序清单94.1 主程序清单94.2 Ethernet类94.3 线程Athread104.4 线程Bthread125. 运行结果与运行情况145.1 运行结果1155.2 运行结果2165.3 运行结果3186 调试记录186.1 “全局变量”的实现186.2 引用同一个对象196.3 冲突的实现206.4 随机函数237 自我评析和总结247.1课设计中遇到的问题247.2.课程设计总结25模拟Ethernet帧的发送过程1.设计题目与要求1.1 设计题目模拟Ethernet帧的发送过程。问题描述:编写程序模拟Ethernet结点的数据发送流程。用两个线程来代表主机,用一个双字型变量来模拟总线,通过带有冲突检测的载波侦听多路访问CSMA/CD算法来实现对总线的争用和碰撞的解决。同时以字符串提示的形式来说明发送的成功,失败与碰撞。1.2设计要求1.2.1 初始条件:(1)学习相关知识(2)C/C+/VC/VB/JAVA语言(3)PC机一台1.2.2 具体要求编写程序模拟Ethernet节点的数据发送流程。具体要求:l 用两个线程a和b来模拟Ethernet上的两台主机。l 用一个双字类型变量Bus来模拟总线(将其初始化为“0”,并且总线等于“0“时表示总线空闲)。l 两个子线程向总线发送自己的数据。数据用该线程的线程号进行模拟,发送数据用线程号和Bus的“或”操作进行模拟(即Bus=Bus|ID,ID为该线程的线程号)。l 每台主机需向总线上成功发送10次数据,如果其中某次数据发送失败,则该线程结束。l 发送流程必须遵循CSMA/CD。随即延迟算法中的冲突窗口取0.0005.在数据发送成功(即Bus=ID)后,报告”ID send success”,产生冲突(即Bus!=ID)后报告”ID send conllision”,发送失败(即冲突计数值为0)后报告”ID send failure”。随着主机发送成功次数增加,报告其已发送成功的次数,如“主机A发送成功数=3”。2. 总的设计思想及系统平台、语言、工具等2.1理论学习2.1.1 Ethernet帧的发送过程 载波侦听过程:Ethernet中每个结点利用总线发送数据,总线是每个结点共享的公共传输介质。所以结点在发送一个帧前,必须侦听总线是否空闲。由于Ethernet的数据采用曼彻斯特编码方式,所以可以通过判断总线电平是否跳变来确定总线是否空闲。若总线空闲,就可以启动发送,否则继续侦听。 冲突检测:在数据发送过程中,可能会产生冲突(冲突是指总线上同时出现两个或两个以上的发送信号,它们叠加后的信号波形与任何发送结点输出的信号波形不相同。因为可能有多个主机都在侦听总线,当它们侦听到总线空闲时,都会往总线上发送数据)。 随机延迟后重发。在检测到冲突、停止发送后,结点进行随机延迟后重发。若重发16次后还不成功,则宣告发送失败,取消该帧的发送。随机延迟的计算方法一般采用截止二进制指数后退算法。该算法可表示为:。其中为结点重新发送需要的后退延迟时间,为冲突窗口值(冲突窗口为总线最大长度和电磁波在介质中的传播速度比值的2倍),R为随机数,k的取值,n为该帧已被发送的次数。2.1.2 Ethernet帧接收流程帧接收流程大致可以分为以下三个步骤:l 检查是否发生冲突,若发生冲突,则丢弃该帧;若没有冲突,进入下一步。l 检查该帧的目的地址看是否可以接收该帧,若可以接收,则进入下一步。l 检查CRC检验和LLC数据长度。若都正确,接收该帧,否则丢弃。2.2 总的设计思想 由于题目中要求了用两个线程来模拟主机,因此可以定义线程ATHREAD和线程BTHREAD来共享总线Bus。因此为了使程序的逻辑结构非常清晰,我运用了四个类,其中两个类是线程ATHREAD和BTHREAD,一个类为总线类Ethernet,其中包含了获取总线状态,设置总线状态,获取线程A的线程号和获取线程B的线程号这几个方法。 还有一个类是主类EthernetSample,用于创建以上三个类的对象。总线争用:总线初值设置为Bus=0,表示总线为空闲,当线程准备发送数据时,首先侦听,也就是获取总经的状态。调用Ethernet中的getBus()方法。如果所得总线的忙,就循环一直侦听,直到总线转为空闲;如果总线是闲状态,就表示现在可以发送数据,但是为了避免如下情况:当线程A完后发现总线是空闲态,就准备发送数据,在监听完毕到发送数据这个过程中,线程B也开始监听总线,并且也检测出来是闲,这时线程B也会占用总线而发送数据。这个情况也就产生了碰撞Collision。遇到碰撞只能停止发送,然后得用截止二进制指数后退算法来达到延时.延时过后继续侦听。2.3系统平台、语言、工具设计语言:JAVA语言所用工具:java环境-JDK1.5.0_12 编译器TEXTPAD473 3 数据结构与模块说明(功能与流程图)3.1 详细设计 主机A主机B算法描述:1创建两个线程A和B模拟两个主机2设置初始值,如成功次数,冲突计数器初始值,冲突窗口值等3监听总线,如果忙就跳转到10步4模拟发送包为总线状态和线程A的线程号的或运算的结果,如Bus=Bus|ID15检测是否有冲突,如果没有,就在前端屏幕上显示发送成功以及总共发送成功的次数。6将冲突计数器复原为16,同时内存清零。7如果有冲突,就显示有冲突8随机延迟重发,延迟算法用截止二进制指数后退算法9跳转到第3步。10总线忙,循环监听,跳转到第3步。3.2 数据结构 public int Bus=0; /用于表示总线忙闲的变量,0表示闲,1表示忙 public int ID1=1; /线程1的线程号 public int ID2=2; /线程2的线程号 int CollisionCounter=16; /冲突计数器初始值为16double collisionWindow=0.005; /冲突窗口值取0.0053.2.1 主程序调用 public class EthernetSample public static void main(String args) /主函数/ TODO 自动生成方法存根Ethernet ethernet=new Ethernet(); /创建Ethernet类的对象Athread threadone=new Athread(ethernet); /创建Athread类的对象Bthread threadtwo=new Bthread(ethernet);/创建Bthread类的对象threadone.start(); /运行线程threadonethreadtwo.start(); /运行线程threadtwo 3.2.2 无冲突模块if(bBus=bID2) /无冲突System.out.println(bID2+ Send Success!); /发送成功ethernetref.setBus(bBus); /设置总线状态this.bBus=ethernetref.getBus(); /获取总线状态 CollisionCounter=16;try Thread.sleep(Math.abs(random.nextInt()%9);/休眠0-9毫秒 catch (InterruptedException e) /捕捉异常i+; /发送成功数加1System.out.print(The times that B sendding is +i+n); /输出发送成功的次数bBus=0; /内存清零ethernetref.setBus(bBus); /设置总线状态try /捕捉异常Thread.sleep(6); catch (InterruptedException e)if(i0) /随机延迟重发,延迟算法用截断二进制指数后退算法double zhouwei=randNum*Math.pow(2,(CollisionCounter10)?10:CollisionCounter)*collisionWindow;try Thread.sleep(long)(zhouwei); catch (InterruptedException e) continue; /下一次尝试发送3.2.4 截止二进制指数后退算法 if(CollisionCounter0) /随机延迟重发,延迟算法用截断二进制指数后退算法double zhouwei=randNum*Math.pow(2,(CollisionCounter10)?10:CollisionCounter)*collisionWindow;try Thread.sleep(long)(zhouwei); catch (InterruptedException e) / TODO 自动生成 catch 块/e.printStackTrace();3.3.算法流程图:3.3.1主程序3.3.2 Ethernet类流程图3.3.3线程A,B的流程图:4程序清单4.1 主程序清单 import classPackage.Athread;import classPackage.Bthread;import classPackage.Ethernet;public class EthernetSample /* * param args */public static void main(String args) /主函数/ TODO 自动生成方法存根Ethernet ethernet=new Ethernet(); /创建Ethernet类的对象Athread threadone=new Athread(ethernet); /创建Athread类的对象Bthread threadtwo=new Bthread(ethernet);/创建Bthread类的对象threadone.start(); /运行线程threadonethreadtwo.start(); /运行线程threadtwo 4.2 Ethernet类package classPackage;public class Ethernet public int Bus=0; /用于表示总线忙闲的变量,0表示闲,1表示忙 public int ID1=1; /线程1的线程号 public int ID2=2; /线程2的线程号/* * return bus */public int getBus() /定义获取总线状态的方法return Bus;/* *set bus */public void setBus(int bBus) /设置总线的状态 Bus=bBus;/* * return iD1 */public int getID1() /定义获取线程1的线程号的方法return ID1;/* * return iD2 */public int getID2() /定义获取线程2的线程号的方法return ID2; 4.3 线程Athread/* * */package classPackage;/产生随机数的包import java.util.Random;import classPackage.Ethernet;public class Athread extends Threadint aBus;int aID1;Random random=new Random();/产生随机数Ethernet ethernetref; /产生一个Ethernet的对象 public Athread(Ethernet ethernet) /构造方法 this.ethernetref=ethernet; this.aBus=ethernet.getBus(); /获取总线状态 this.aID1=ethernet.getID1(); /获取线程b的线程号 public void run()int i=0; /发送成功次数int CollisionCounter=16; /冲突计数器初始值为16double collisionWindow=0.005; /冲突窗口值取0.005int randNum=Math.abs(random.nextInt()%5); /产生0-5之间的随机数for(int j=0;j10;j+) try /捕捉异常Thread.sleep(2); /休眠2毫秒 catch (InterruptedException e)/ TODO 自动生成 catch 块/e.printStackTrace();/System.out.print(THE result of A is +aBus+n);if(aBus=0) /总线空闲aBus=aBus|aID1; /将总线状态与线程2的线程号进行或运算,作为发送的数据ethernetref.setBus(aBus); /设置总线状态 try Thread.sleep(1); /休眠1毫秒 catch (InterruptedException e) /捕捉异常 /TODO 自动生成 catch 块/e.printStackTrace();aBus=ethernetref.getBus(); /获取总线状态if(aBus=aID1) /无冲突ethernetref.setBus(aBus);System.out.println(new String(aID1+ Send Success!);/发送成功CollisionCounter=16;try Thread.sleep(Math.abs(random.nextInt()%4); /随机休眠0-4毫秒 catch (InterruptedException e)/ TODO 自动生成 catch 块/e.printStackTrace();i+; /发送成功数加1System.out.print(The times that A sendding is +i+n); /输出发送成功的次数aBus=0; /内存清零 ethernetref.setBus(aBus); /设置总线状态 try /捕捉异常Thread.sleep(5); catch (InterruptedException e)/ TODO 自动生成 catch 块/e.printStackTrace();if(i0) /随机延迟重发,延迟算法用截断二进制指数后退算法double zhouwei=randNum*Math.pow(2,(CollisionCounter10)?10:CollisionCounter)*collisionWindow;try Thread.sleep(long)(zhouwei); catch (InterruptedException e) / TODO 自动生成 catch 块e.printStackTrace();continue; /下一次尝试发送elseSystem.out.println(new String(aID1+ Send Failure!); /发送失败elseSystem.out.print(A:the line is busy!n); /总线忙continue; 4.4 线程Bthreadpackage classPackage;import java.util.Random; /产生随机数的包public class Bthread extends Thread int bBus;int bID2;Random random=new Random(); /产生随机数Ethernet ethernetref; /产生一个Ethernet的对象public Bthread(Ethernet ethernet) /构造方法this.ethernetref=ethernet; bBus=ethernet.getBus(); /获取总线状态bID2=ethernet.getID2(); /获取线程b的线程号public void run()int i=0; /发送成功次数int CollisionCounter=16; /冲突计数器初始值为16double collisionWindow=0.005; /冲突窗口值取0.005int randNum=Math.abs(random.nextInt()%3); /产生0-3之间的随机数for(int j=0;j10;j+) bBus=ethernetref.getBus(); /获取总线状态/System.out.print(The result1 is +ethernetref.getBus()+n);if(bBus=0) /总线空闲Bus=bBus|bID2; /将总线状态与线程2的线程号进行或运算,作为发送的数据ethernetref.setBus(bBus); /设置总线状态 try Thread.sleep(12); /休眠12毫秒 catch (InterruptedException e) /捕捉异常 /TODO 自动生成 catch 块/e.printStackTrace();bBus=ethernetref.getBus(); /获取总线状态if(bBus=bID2) /无冲突System.out.println(bID2+ Send Success!); /发送成功ethernetref.setBus(bBus); /设置总线状态this.bBus=ethernetref.getBus(); /获取总线状态 /System.out.print(the result2 is +ethernetref.Bus+n); CollisionCounter=16;try Thread.sleep(Math.abs(random.nextInt()%9);/休眠0-9毫秒 catch (InterruptedException e) /捕捉异常/ TODO 自动生成 catch 块/e.printStackTrace();i+; /发送成功数加1System.out.print(The times that B sendding is +i+n); /输出发送成功的次数bBus=0; /内存清零ethernetref.setBus(bBus); /设置总线状态/System.out.print(the result3 is+ethernetref.Bus+n);try /捕捉异常Thread.sleep(6); catch (InterruptedException e)/ TODO 自动生成 catch 块/e.printStackTrace();if(i0) /随机延迟重发,延迟算法用截断二进制指数后退算法double zhouwei=randNum*Math.pow(2,(CollisionCounter10)?10:CollisionCounter)*collisionWindow;try Thread.sleep(long)(zhouwei); catch (InterruptedException e) / TODO 自动生成 catch 块/e.printStackTrace();continue; /下一次尝试发送elseSystem.out.println(bID2+ Send Failure!); /发送失败else System.out.print(B:the line is busy!n); /总线忙continue;5. 运行结果与运行情况我运行的环境是TEXTPAD473,在上面进行编辑,编译,运行,由于大二上学期开设过一门java的选修课,比较喜欢JAVA语言,因此此次设计就采用的是JAVA程序进行设计。在自己的PC机上装上JDK1.5.0_12后,设置环境变量之后,JAVA程序就可以运行了。为了方便编辑,编译和运行,我在自己的电脑上装了TEXTPAD473这个编译工具。具体的操作步骤如下:1. 打开TEXTPAD473,编制程序。2. 编译程序。Tools-Compile java3. 运行程序。Tools-Run java application4. 就可以看到运行结果了。5.1 运行结果1图2:实验运行结果 依上图所示,这是一次运行的结果,由图可以看出,程序开始运行时,线程A首先运行,并且这时由于线程B还没有启动,因此它抢占了总线,成功的发送了一次,输出1 Send Success。在线程A发送的过程中,由于在准备发送之间休眠了一段时间(此时并未改变总线状态),这时B也尝试着发送,刚开始,B侦听总线闲(由于总线状态没有被A改变),于是它开始发送,但是发送了一半时就会与A发送的数据产生碰撞。这时B就会产生碰撞,输出2 Send Collision!然后输出A发送成功的次数1次。此后A继续发送,并且发送成功,同时输出发送成功的次数2次。与第一次同理,B主机发生碰撞,紧接着,A主机发送,并且发送成功。依次进行发送,最后当A机和B机都发送过10次之后,就退出程序,此外由于随机延时的原因,会出现许多随机的发送过程,正是由于这种随机,使得整个发送过程可以模拟出现实的Ethernet帧的发送过程。5.2 运行结果2图3:实验运行结果由图(3)可以看出,这是另一次运行的结果,与图(2)的运行结果相比,它们在前期有很大的相似处,但是到了后面的发送过程中就会出现较大的不同之处,这正是程序中的随机延时的结果。程序开始运行时,线程A首先运行,并且这时由于线程B还没有启动,因此它抢占了总线,成功的发送了一次,输出1 Send Success。在线程A发送的过程中,由于在准备发送之间休眠了一段时间(此时并未改变总线状态),这时B也尝试着发送,刚开始,B侦听总线闲(由于总线状态没有被A改变),于是它开始发送,但是发送了一半时就会与A发送的数据产生碰撞。这时B就会产生碰撞,输出2 Send Collision!然后输出A发送成功的次数1次。此后A继续发送,并且发送成功,同时又会出现与B发生碰撞的过程,B输出2 Send Collision。同时A输出发送成功的次数2次。紧接着,A主机发送,并且发送成功。依次进行发送,最后当A机和B机都发送过10次之后,就退出程序。在发送的中间过程中,发现了B线程先碰撞,然后A线程再碰撞。其中的原因是,开始A发送的过程中,B侦听,以为总线空闲,就去发送数据,结果发生碰撞。之后就采用随机二进制后退算法进行延时,延时完毕后,再次侦听总线,总线空闲,开始发送。而这时候,A和B以前的角色互换,A误以为总线空闲,发送数据,结果发生碰撞。5.3 运行结果3图3:实验运行结果6 调试记录6.1 “全局变量”的实现 在JAVA语言中,为了保护类的封装性,没有全局变量之说,但是有的时候,运用全局变量是非常必要的,全局变量可以在某种程度上简化编程和方便理解。JAVA中没有全局变量,那么应该怎么办呢?开始为这个问题困扰了很长时间,上网查阅了许多资料,发现许多人都和我有相同的困惑,但是并没有提供解决方案。之后,我又把当初的JAVA课本看了看,发现其实可以通过方法调用来代替全局变量。代码如下: public int Bus=0; /用于表示总线忙闲的变量,0表示闲,1表示忙 public int ID1=1; /线程1的线程号 public int ID2=2; /线程2的线程号/* * return bus */ public int getBus() /定义获取总线状态的方法return Bus;/* *set bus */public void setBus(int bBus) /设置总线的状态 Bus=bBus;/* * return iD1 */public int getID1() /定义获取线程1的线程号的方法return ID1;/* * return iD2 */public int getID2() /定义获取线程2的线程号的方法return ID2; 在这个类中,定义了获取总线状态,设置总线状态,获取线程Athread的线程号,获取线程Bthread的线程号这四个方法。当线程类Athread创建Ethernet的一个对象时,就可以访问这四个方法了,从而达到了“全局变量”的功效。6.2 引用同一个对象 为了使程序在逻辑上看起来非常清晰,我将所有的方法都放在一个类中,然后利用类的对象的方法调用来实现对方法的控制和管理。但是正是由于这个思想,就面临一个问题,两个线程Athread和Bthread都要创建一个对象,但是这两个对象中如何通信呢,如果线程Athread调用方法setBus()将总线状态改变了,表面上看来,是改变了类Ethernet中的总线状态BUS,其实只是改变了Athread中创建的一个Ethernet类的对象threadone。同理线程Bthread改变的也只是一个对象中的总线状态,这样两个线程之间的通信就存在不一致性,以至于程序运行出来的结果非常蹊跷:在A线程访问的同时,B线程也可以访问。显然这种结果是不正确的。后来,想到了一个办法,就是让两个线程引用同一个对象,代码如下:Ethernet ethernet=new Ethernet(); /创建Ethernet类的对象Athread threadone=new Athread(ethernet); /创建Athread类的对象Bthread threadtwo=new Bthread(ethernet);/创建Bthread类的对象这样两个线程之间就可以进行通信了,由于改变的都是同一个对象中的变量,所以它们之间的读写总线也不会存在不一致性了。6.3 冲突的实现 在冲突在实现方面遇到了很大的困难,可能是开始的时候对整个Ethernet帧的发送过程没有特别清楚的认识,以致于在编写程序的过程中,按照自己想当然的想法在写,虽然程序可以正常运行,并且也可以实现部分功能,但是对于碰撞的实现,还是心有余而心不足,后来仔细思考整个发送过程之后,在保证对这个过程有烂熟于心的理解之后,审核了程序,发现冲突的实现是可以通过延时来解决的。在加入延时之前,程序运行的结果如下:由上图可知,两个线程都没有发生过冲突,开始我还以为这是随机因素,后来运行了许多次之后,发现始终不能产生碰撞,应该是程序的问题,在加入了延时之后,由于具体的延长多少时间控制不当,导致两个线程一直碰撞,都不能正常发送,如下图所示:这种情况是极其不正常的,自然也不能完成正常的Ethernet帧的发送过程。在经过多次试验之后,终于选定了合适的延时时间,才可以达到预期的效果。如下图所示:6.4 随机函数 在时间函数方面,可以调用数学函数中的随机函数Math. Random,来产生随机数,但是开始调用了之后,系统一直报错,说negative position in Math.random,后来自己又写了一个小程序之后,发现,原来Math. Random产生的是一个负数,但是按照程序的需要,是要用正数,改过之后的函数调用为Math.abs(random.nextInt()%4),其中random.nextInt()%4为产生0-4之间的随机数。7 自我评析和总结7.1课设计中遇到的问题 1在这个实验过程中,由于在写程序之前,首先应该画流程图,然后再写程序。在画流程图的过程中,我想当然的应用了全局变量,但是真正的在程序实现的过程中,才恍然大悟原来JAVA语言中并没有全局变量这一说,这时就感觉举步维艰。但是经过思考;JAVA中没有全局变量,为什么我不能通过其他的方法来达到使用全局变量的目的呢。后来就想到了JAVA语言的强项类中的方法调用。首先创建类的一个对象,然后调用这个对象中的方法,从而非常灵活的实现了“全局变量”的功能。2通过以上第1点是可以初步实现“全局变量”,但是真正到了实现的时候,又在构造函数这个方面出现了问题。因为如果在类的构造函数中创建了一个对象之后,只能在这个构造函数中使用,如果在这个类的其他程序块中使用,就会报错。后来想到了一个办法,就是在构造函数之间就创建另一个Ethernet类的对象,然后在构造方法中,对其进行赋值,这时前面创建的对象就可以在整个类中的所有的程序块中使用了。代码如下所示:Ethernet ethernetref; /产生一个Ethernet的对象 public Athread(Ethernet ethernet) /构造方法 this.ethernetref=ethernet; this.aBus=ethernet.getBus(); /获取总线状态 this.aID1=ethernet.getID1(); /获取线程b的线程号 这时对象ethernetref就可以在整个程序块中使用了。3以前对JAVA中的Sleep函数没有很好的认识,只知道它是用在多线程中的,但是这个课程设计中对Sleep函数的使用非常频繁,因此这个课程设计是学习Sleep的用法的绝佳时期。Sleep函数是实现碰撞的一个必不可少的途径,在没有使用这个函数之前,程序运行的结果说明,始终都不能实现碰撞,后来经过思考了之后,明白,原来通过Sleep而产生的延时,就是在给另一个线程制造机会,让它也开始运行,这样两个线程就可能在争用总线的过程中产生碰撞,这样更加符合实际情况。在使用Sleep的时候,开始以为它和C+语言中的sleep(5)是一个意思,表明暂停5秒钟,后来使用之后,发现暂停的时候远远小于5秒钟,结果一瞬间就显示了,究其原因,原来是因为在JAVA语言中的sleep(5)表示暂停5毫秒,时间远远短于5秒钟。4当涉及到JAVA语言中的随机函数时,由于以前并没有用过这个函数,所以学习这个函数的过程也是非常美好的。通过上网查资料,可以得到随机函数RANDOM是在类MATH中的。并且其用法如下:Math.abs(random.nextInt()%4),上面用到了abs这个函数是因为rand

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论