版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
计算机网络20世纪60年代出现,经历了20世纪70年代、80年代和90年代的发展,进入21世纪后,计算机网络已经成为信息社会的基础设施,深入到人类社会的方方面面,与人们的工作、学习和生活息息相关。计算机网络是通过传输介质、通信设施和网络通信协议,把分散在不同地点的计算机设备互连起来的,实现资源共享和数据传输的系统。网络编程,就是在一定的协议下,实现多台设备(计算机)之间通信的程序。Java语言对网络编程提供了良好的支持。通过其提供的接口我们可以很方便地进行网络编程。本模块通过“文件上传”案例介绍网络编程的过程。模块介绍思维导图教学大纲能力目标◎能够编写TCP协议下的数据传输程序知识目标◎了解网络通信协议◎理解TCP和UDP的协议特点◎掌握IP地址和端口号的作用◎熟悉TCP协议下两个JDK常用类的使用◎掌握TCP通信的基本实现学习重点◎TCP通信的应用◎TCP通信程序的实现学习难点◎TCP通信“三次握手”过程◎TCP通信程序的实现任务9.1文件上传程序设计任务目标了解网络通信协议;理解TCP和UDP的协议特点;理解TCP协议下文件上传过程;实现TCP协议下文件传输程序。任务9.1文件上传程序设计网盘是由互联网公司推出的在线存储服务,它已经融入了人们的日常生活中。人们在利用网盘上传资料时,实际上是一个使用客户端读取本地文件,把文件上传到服务器,服务器再把上传的文件保存到服务器硬盘上的过程。本节要求了解网络通信的基本原理,编写使用TCP网络通信程序,实现将客户端的“c:\\1.jpg”文件上传至服务器端的硬盘“d:\\upload\\”中。任务描述任务9.1文件上传程序设计9.1.1网络通信协议9.1.1.1网络通信协议概述
要实现多台计算机之间的通信,需要遵守一定的规则,如同人与人之间相互交流是需要遵循一定的规矩一样,计算机之间能够进行相互通信是因为它们都共同遵守一定的规则,即网络通信协议。协议(protocol)是定义计算机如何通信的一组明确的规则,包括地址格式、数据如何分包等。针对网络通信的不同方面,定义有很多不同的协议,如HTTP、FTP、TCP协议等。知识准备任务9.1文件上传程序设计
通过网络发送数据是一项复杂的操作,必须仔细地协调网络的物理特性以及所发送数据的路径特征。为了对应用程序开发人员和最终用户隐藏这种复杂性,网络通信的不同方面被分解为多个层。每一层表示为物理硬件(即线缆和电流)与所传输信息之间的不同抽象层次。在理论上,每一层只与紧挨其上和其下的层对话。将网络分层,这样就可以修改甚至替换某一层的软件,只要层与层之间的接口保持不变,就不会影响到其他层。
TCP/IP协议(TransmissionControlProtocol/InternetProtocol,传输控制协议/因特网互联协议)是Internet最基本、最广泛的协议。它定义了计算机如何连入因特网,以及数据如何在它们之间传输的标准。它的内部包含一系列的用于处理数据通信的协议,并采用了4层的分层模型,每一层都呼叫它的下一层所提供的协议来完成自己的需求,如图9-1所示。任务9.1文件上传程序设计
图9-1中,TCP/IP协议中的四层分别是应用层、传输层、网络层和链路层,每层分别负责不同的通信功能。链路层是用于定义物理传输通道,通常是对某些网络连接设备的驱动协议,例如针对光纤、网络提供的驱动。网络层是整个TCP/IP的核心,它主要用于将传输的数据进行分组,将分组数据发送到目标计算机或者网络。传输层主要使网络程序进行通信,在进行网络通信时,可以采用TCP协议,也可以采用UDP协议。应用层主要负责应用程序的协议,例如HTTP协议、FTP协议等。图9-1TCP/IP网络模型在JDK中提供了包用于专注网络程序开发,包中提供了两种常见的网络协议支持,分别是TCP和UDP。任务9.1文件上传程序设计9.1.1.2TCP协议
TCP(TransmissionControlProtocol)全称是传输控制协议,是一种面向连接的通信协议,即传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。在TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠,这三次交互被称为“三次握手”。“三次握手”的具体过程如下:·第一次握手,客户端向服务器端发出连接请求,等待服务器确认。·第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求。·第三次握手,客户端再次向服务器端发送确认信息,确认连接。
整个交互过程如图9-2所示。任务9.1文件上传程序设计
完成三次握手,连接建立之后,客户端和服务器就可以进行数据传输了。由于面向连接的特性,TCP协议可以保证传输数据的安全,所以应用十分广泛,例如下载文件、浏览网页等。图9-2TCP协议通信——“三次握手”任务9.1文件上传程序设计9.1.1.3UDP协议
UDP(UserDatagramProtocol)全称是用户数据报协议,是一种面向无连接的协议,即在使用UDP协议传输数据时,数据的发送端和接收端不需要建立逻辑连接。简单的说,就是当一台计算机向另一台计算机发送数据时,发送端不会确认接收端是否存在,可以直接将数据、数据源和目的地都封装在数据包中发送出去。同样接收端在收到数据时,也不会向发送端反馈是否收到数据。和TCP不同的是,UDP不需要在发送数据前进行三次握手建立连接,只要想发数据就可以发送数据,只是数据的搬运工,不会对数据报文进行任何拆分和拼接操作。任务9.1文件上传程序设计
正由于无连接性,UDP不能保证数据的完整性,具有不可靠性。另外,UDP没有拥塞控制,一直会以恒定的速度发送数据,即使网络条件不好,也不会对发送速率进行调整,那么在网络条件不好的情况下可能产生丢包,因此在传输重要数据时不建议使用UDP协议,以免丢失重要数据。但是其优点也很明显,使用UDP协议消耗的资源小,每个数据包的大小限制在64k以内,通信效率高,所以通常会用于音频、视频这些实时性要求高的场景。例如视频会议、群聊天等这些即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响的应用。任务9.1文件上传程序设计TCPUDP是否连接面向连接无连接是否可靠可靠传输,使用流量控制和塞控制不可靠传输,不使用流量控制和塞控制对象数量只支持一对一通信支持一对一,一对多,多对一和多对多交互通信适用场景适用于要求可靠传输的应用,如文件传输适用于实时应用,如IP电话、视频会议、直播等表9-1TCP和UDP的对比任务9.1文件上传程序设计9.1.1.4IP地址和端口号
在Java中,网络编程需要掌握三个要素,除了协议以外,还有IP地址和端口号。网络的通信,本质上是两个进程(应用程序)的通信。“协议+IP地址+端口号”三元组合可以标识网络中的进程,那么进程就可以利用这个标识与其它进程进行交互。
IP地址是InternetProtocolAddress的简写,指的是互联网协议地址,用来给一个网络中的计算机设备做唯一的编号。假如我们把“个人电脑”比作“一台电话”的话,那么“IP地址”就相当于“电话号码”。IP地址分为IPv4和IPv6。IPv4是一个32位的二进制数,通常被分为4个字节,表示成a.b.c.d的形式,例如00。其中a、b、c、d都是0~255之间的十进制整数,那么最多可以表示42亿个。由于互联网的蓬勃发展,互联网对IP地址的需求量愈来愈大,但是网络地址资源有限,使得IP的分配越发紧张。为了扩大地址空间,拟通过IPv6重新定义地址空间,采用128位地址长度,每16个字节一组,分成8组十六进制数,表示成ABCD:EF01:2345:6789:ABCD:EF01:2345:6789,以解决了网络地址资源数量不够的问题。任务9.1文件上传程序设计
如果说IP地址可以唯一标识网络中的设备,那么端口号就可以唯一标识设备中的进程(应用程序)了。端口号是一个逻辑端口,它用两个字节表示的整数,取值范围是0~65535。每当打开一个网络软件,操作系统都会为网络软件分配一个随机的或者是系统要指定的端口号。0~1023之间的端口号都已经被用于一些知名的网络服务和应用,普通的应用程序需要使用1024以上的端口号。如果端口号被另外一个服务或应用所占用,会导致当前程序启动失败。任务9.1文件上传程序设计9.1.2TCP通信程序设计
TCP通信能实现两台计算机之间的数据交互,TCP连接时必须明确服务器端(Server)与客户端(Client)。两端通信时,服务端程序需要事先启动,它不可以主动连接客户端,只能等待客户端的连接。然后客户端主动连接服务器端,连接成功才能通信。连接过程中包含一个IO字节流对象,客户端和服务端就用这个IO流对象进行通信。需要注意的是,当多个客户端同时和服务端交互时,服务端必须明确和哪个客户端进行交互,并且需要使用多个IO流对象。
Java在net包中提供了两个类用于实现TCP通信程序。任务9.1文件上传程序设计
(1)表示服务端的类:.ServerSocket类表示。该类实现了服务器套接字,套接字指的是两台设备之间通讯的端点。创建ServerSocket对象,相当于开启一个服务,该对象等待通过网络的请求,也就是等待客户端的连接。ServerSocket类的主要构造方法和成员方法如表9-2所示。表9-2ServerSocket类的主要构造方法和成员方法方法声明功能描述publicServerSocket(intport)使用该构造方法在创建ServerSocket对象时,就可以将其绑定到一个指定的端口号上,参数port就是端口号。publicSocketaccept()侦听并接受连接,返回一个新的Socket对象,用于和客户端实现通信。该方法会一直阻塞直到建立连接。任务9.1文件上传程序设计
(2)表示客户端的类:.Socket类表示。该类实现客户端套接字。创建Socket对象,向服务端发出连接请求,服务端响应请求,两者建立连接开始通信。Socket类的主要构造方法和成员方法如表9-3所示。表9-3Socket类的主要构造方法和成员方法方法声明功能描述publicSocket(Stringhost,intport)创建套接字对象并将其连接到指定主机上的指定端口号。如果指定的host是null,则相当于指定地址为回送地址。publicInputStreamgetInputStream()返回此套接字的输入流。关闭生成的InputStream也将关闭相关的Socket。publicOutputStreamgetOutputStream()返回此套接字的输出流。关闭生成的OutputStream也将关闭相关的Socket。publicvoidclose()关闭此套接字。一旦一个socket被关闭,它不可再使用。关闭此socket也将关闭相关的InputStream和OutputStream。publicvoidshutdownOutput()禁用此套接字的输出流。任何先前写出的数据将被发送,随后终止输出流。任务9.1文件上传程序设计
从通信逻辑上来看,TCP网络通信的两端程序编写主要步骤如下:①服务端启动,创建ServerSocket对象,指定端口号,等待连接。②客户端启动,创建Socket对象,构造方法绑定服务器的IP地址和端口号,请求连接。③服务端接收连接,调用ServerSocket对象中的accept()方法,返回请求的客户端对象Socket。④客户端使用Socket对象的getOutputStream()方法获取网络字节输出流OutputStream对象,然后使用网络字节输出流OutputStream对象中的write()方法,给服务器发送数据。⑤服务端使用Scoket对象的getInputStream()方法获取网络字节输入流InputStream对象,然后使用网络字节输入流InputStream对象中的read()方法,读取客户端发送的数据。到此,客户端向服务端发送数据成功,接下来服务端向客户端回写数据。任务9.1文件上传程序设计⑥服务端使用Socket对象中的getOutputStream()方法获取网络字节输出流OutputStream对象,然后使用网络字节输出流OutputStream对象中的write()方法,给客户端回写数据。⑦客户端使用Scoket对象的getInputStream()方法获取网络字节输入流InputStream对象,然后使用网络字节输入流InputStream对象中的read()方法,读取服务端回写的数据。⑧客户端释放Socket资源,断开连接。⑨服务端释放Socket和ServerSocket资源。图9-3TCP网络通信逻辑图任务9.1文件上传程序设计
需要注意的是,客户端和服务端交互时必须使用Socket中提供的网络流,不允许使用自己创建的流对象。当创建客户端对象Socket的时候,就会主动请求服务器,要求经过3次握手建立连接通路。如果此时服务器没有启动,则会抛出连接被拒绝的异常(ConnectException:Connectionrefused:connect);如果服务器已经启动,那么交互就可以顺利进行了。任务9.1文件上传程序设计
接下来用一个案例来演示TCP网络通信程序的编写过程,服务器端程序如例9-1所示,客户端程序如例9-2所示。importjava.io.*;import.*;publicclassExample9_1{publicstaticvoidmain(String[]args)throwsIOException{//1.创建ServerSocket对象,绑定端口,开始等待连接。ServerSocketserver=newServerSocket(8888);//2.接收连接,使用accept方法,返回socket对象。Socketsocket=server.accept();//3.通过socket获取输入流InputStreamis=socket.getInputStream();//4.一次性读取数据//4.1创建字节数组byte[]bytes=newbyte[1024];//4.2将数据读取到字节数组中intlen=is.read(bytes);//4.3解析数组,打印字符串信息System.out.println(newString(bytes,0,len));
例9-1Example9_1.java任务9.1文件上传程序设计/*----------服务端回写数据-----------*///5.通过socket获取输出流OutputStreamos=socket.getOutputStream();//6.回写数据os.write("收到,谢谢".getBytes());//7.关闭资源socket.close();server.close();}}例9-1Example9_1.java任务9.1文件上传程序设计importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;import.Socket;publicclassExample9_2{publicstaticvoidmain(String[]args)throwsIOException{//1.创建Socket(ip,port),确定连接到哪里。Socketsocket=newSocket("",8888);//2.通过Scoket,获取输出流对象OutputStreamos=socket.getOutputStream();//3.写出数据os.write("你好,服务器".getBytes());/*----------客户端解析服务端的回写数据-----------*///4.通过Scoket,获取输入流对象。InputStreamis=socket.getInputStream();//5.读取数据byte[]bytes=newbyte[1024];intlen=is.read(bytes);System.out.println(newString(bytes,0,len));//6.关闭资源socket.close();}}例9-2Example9_2.java任务9.1文件上传程序设计
完成程序编写后,首先运行服务器端程序Example9_1.java,然后运行客户端程序Example9_2.java。从这两个例子的运行结果中看到,服务器端结果显示“你好,服务器”,表示收到来自客户端的数据信息,如图9-4所示。客户端结果显示“收到,谢谢”,表示收到来自服务器端的回写数据,如图9-5所示。图9-4Example9_1运行结果(服务器端)图9-5Example9_2运行结果(客户端)任务实施1.任务分析文件上传的原理,本质上就是文件的复制。客户端和服务器和本地硬盘进行读写,需要使用自己创建的字节流对象,即本地IO流。客户端和服务器之间进行读写,必须使用Socket中提供的字节流对象,即网络IO流。除了明确字节流对象,还要明确数据源和目的地。客户端的数据源是客户端文件所在地址,目的地是服务器;服务端的数据源是客户端上传的文件,目的地是服务器的硬盘,即要存放文件的地址。文件上传的过程如图9-6所示。任务9.1文件上传程序设计(1)客户端使用本地字节输入流,读取要上传的文件;(2)客户端使用网络字节输出流,把读取到的文件上传到服务器;(3)服务器使用网络字节输入流,读取客户端上传的文件;(4)服务器使用本地字节输出流,把读取到的文件,保存到服务器的硬盘上;(5)服务器使用网络字节输出流,给客户端回写一个“上传成功”的提示;(6)客户端使用网络字节输入流,读取服务器回写的数据;(7)释放资源。任务9.1文件上传程序设计图9-6文件上传过程2.具体实现步骤(1)客户端实现步骤:①创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源。②创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号。③使用Socket中的getOutputStream()方法,获取网络字节输出流OutputStream对象。④使用本地字节输入流FileInputStream对象中的read()方法,读取本地文件。⑤使用网络字节输出流OutputStream对象中的write()方法,把读取到的文件上传到服务器。⑥使用Socket中的方法getInputStream,获取网络字节输入流InputStream对象。⑦使用网络字节输入流InputStream对象中的read()方法读取服务回写的数据。⑧释放资源(FileInputStream,Socket)。任务9.1文件上传程序设计2.具体实现步骤(2)服务端实现步骤:①创建一个服务器ServerSocket对象,和系统要指定的端口号。②使用ServerSocket对象中的accept()方法,获取到请求的客户端Socket对象。③使用Socket对象中的方法getInputStream,获取到InputStream对象。④判断d:\\upload文件夹是否存在,不存在则创建。⑤创建一个FileOutputStream对象,构造方法中绑定要输出的目的地。⑥使用InputStream对象中的方法read,读取客户端上传的文件。⑦使用FileOutputStream对象中的write()方法,把读取到的文件保存到服务器的硬盘上。⑧使用Socket对象中的getOutputStream()方法,获取到网络字节输出流OutputStream对象。⑨使用网络字节输出流OutputStream对象中的write()方法,给客户端回写“上传成功”。⑩释放资源(FileOutputStream,Socket,ServerSocket)。任务9.1文件上传程序设计3.程序编写服务器端程序如例9-3所示,客户端程序如例9-4所示。任务9.1文件上传程序设计importjava.io.*;import.*;publicclassExample9_4{publicstaticvoidmain(String[]args)throwsIOException{//1.创建服务器,指定端口号ServerSocketserver=newServerSocket(8888);//2.获取到请求的客户端Socketsocket=server.accept();//3.获取到网络字节输入流InputStreamis=socket.getInputStream();//4.判断d:\\upload文件夹是否存在,不存在则创建Filefile=newFile("d:\\upload");if(!file.exists()){file.mkdirs();}//5.创建一个本地字节输出流,绑定要输出的目的地FileOutputStreamfos=newFileOutputStream(file+"\\1.jpg");//6.使用网络字节输入流读取客户端上传的文件intlen=0;
任务9.1文件上传程序设计byte[]bytes=newbyte[1024];while((len=is.read(bytes))!=-1){//7.使用本地字节输出流,把读取到的文件保存到服务器的硬盘上fos.write(bytes,0,len);}//8.获取到网络字节输出流//9.使用网络字节输出流,给客户端回写“上传成功”socket.getOutputStream().write("上传成功".getBytes());//10.释放资源fos.close();socket.close();server.close();}}任务9.1文件上传程序设计importjava.io.*;import.Socket;publicclassExample9_4{publicstaticvoidmain(String[]args)throwsIOException{//1.创建本地字节输入流,绑定要读取的数据源FileInputStreamfis=newFileInputStream("c:\\1.jpg");//2.创建客户端对象,绑定服务器IP地址和端口号Socketsocket=newSocket("",8888);//3.获取网络字节输出流OutputStreamos=socket.getOutputStream();//4.读取本地文件intlen=0;byte[]bytes=newbyte[1024];while((len=fis.read(bytes))!=-1){//5.把读取到的文件上传到服务器os.write(bytes,0,len);}//6.获取网络字节输入流InputStreamis=socket.getInputStream();//7.读取服务回写的数据while((len=is.read(bytes))!=-1){System.out.println(newString(bytes,0,len));例9-4Example9_4.java}//8.释放资源fis.close();socket.close();}}
完成程序编写后,按“先运行服务器端,后运行客户端”的顺序运行程序,能够看到D盘中生成了一个名为“upload”的文件夹,里面的存放了一个文件,该文件与“c:\\1.jpg”文件一致,说明实现了文件的上传。
需要注意的是,上述代码虽然实现了文件的上传,但无论是客户端还是服务器端,程序都没有停止运行,这是因为受到FileInputStream类的read()方法影响。通过查看API手册可以知道,read(byte[]b)方法功能是“从此输入流中将最多b.length个字节数据读入一个byte数组中,在某些输入可用之前,此方法将阻塞”。在例9-3代码中,客户端中的fis.read(bytes)读取本地文件,读取到-1则结束,然而在while循环里并不会读取到-1,也就不会把结束标记写给服务器端。服务器端中的is.read(bytes)用于读取客户端上传的文件,但由于读不到文件的结束标志,read()方法就会进入到阻塞状态,一直死循环等待结束标记。同样的,客户端中的is.read(bytes)也会因为读取不到服务器回写的数据而进入阻塞状态。
为了能够更加直观看出阻塞现象,现分别对例9-3和例9-4的代码进行修改。任务9.1文件上传程序设计任务9.1文件上传程序设计publicclassExample9_3{publicstaticvoidmain(String[]args)throwsIOException{……//省略例9-3重复代码
System.out.println("服务器端阻塞测试");while((len=is.read(bytes))!=-1){fos.write(bytes,0,len);}
System.out.println("若此语句出现,则说明服务器端未发生阻塞");……}}修改例9-3Example9_3.java任务9.1文件上传程序设计publicclassExample9_4{publicstaticvoidmain(String[]args)throwsIOException{……//省略例9-4重复代码System.out.println("客户端阻塞测试");while((len=is.read(bytes))!=-1){System.out.println(newString(bytes,0,len));}
System.out.println("若此语句出现,则说明客户端未发生阻塞");……}}修改例9-4Example9_4.java
修改后的例9-3和例9-4运行结果分别如图9-7和图9-8所示,可以看到服务器端打印输出语句“服务器端阻塞测试”,但没有出现“若此语句出现,则说明服务器端未发生阻塞”;客户端打印输出“客户端阻塞测试”,但没有出现“若此语句出现,则说明客户器端未发生阻塞”,说明服务器端和客户端均在while中产生了死循环,发生了阻塞现象。任务9.1文件上传程序设计图9-7Example9_3修改后的运行结果(服务器端)图9-8Example9_4修改后的运行结果(客户端)
那么如何解决上述的阻塞问题呢?由于阻塞问题是由于服务器端没有读到结束标记造成的,所以在上传文件后,只需要给服务器写一个结束标记就可以解决问题了。在这里需要用到socket类的shutdownOutput()方法,此方法的作用是禁用此套接字的输出流。对于TCP套接字,任何以前写入的数据都将被发送,并且后跟TCP的正常连接终止序列。现对例9-4的代码再次进行修改。任务9.1文件上传程序设计任务9.1文件上传程序设计publicclassExample9_4{publicstaticvoidmain(String[]args)throwsIOException{……//省略例9-4重复代码while((len=fis.read(bytes))!=-1){os.write(bytes,0,len);}socket.shutdownOutput();InputStreamis=socket.getInputStream();System.out.println("客户端阻塞测试");while((len=is.read(bytes))!=-1){System.out.println(newString(bytes,0,len));}System.out.println("若此语句出现,则说明客户端未发生阻塞");……}}再次修改例9-4Example9_4.java
修改完成后,重新运行例9-3和例9-4程序,其运行结果分别如图9-9和图9-10所示。可以看到服务器端打印输出语句“服务器端阻塞测试”、“若此语句出现,则说明服务器端未发生阻塞”,;客户端打印输出“客户端阻塞测试”、“上传成功”、“若此语句出现,则说明客户器端未发生阻塞”,但没有出现“若此语句出现,则说明客户器端未发生阻塞”,并且程序在完成文件的上传后停止运行,说明成功解决了阻塞问题。任务9.1文件上传程序设计图9-9Example9_3的运行结果(服务器端)图9-10Example9_4的运行结果(客户端)4.程序优化
现对文件上传进行优化,以解决以下两个问题:
(1)文件名称写死的问题。在服务器端中,保存文件的名称如果写死,那么最终导致服务器硬盘只会保留一个文件。建议使用系统时间优化,保证文件名称唯一。
(2)循环接收的问题。在前面的程序中,服务器端只保存一个文件就关闭了,之后的用户无法再上传,这是不符合实际的。使用循环改进,可以不断的接收不同用户的文件。
(3)效率问题。如果多个人需要同时上传文件时,且文件较大时,服务端每接收一个文件可能会耗费几秒钟的时间,此时不能接收其他用户上传,那么效率就会非常低。可以使用多线程技术进行优化。
修改后的服务端代码如例9-5所示。任务9.1文件上传程序设计任务9.1文件上传程序设计importjava.io.*;import.*;importjava.util.Random;publicclassExample9_5{publicstaticvoidmain(String[]args)throwsIOException{ServerSocketserver=newServerSocket(8888);//优化2:让服务器一直处于监听状态//有一个客户端上传文件,就保存一个文件while(true){Socketsocket=server.accept();//优化3:使用多线程技术,提高程序的效率//有一个客户端上传文件,就开启一个线程,完成文件的上传newThread(newRunnable(){//完成文件的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年技术人才租赁合同
- 2024商场瓷砖铺设及维修服务合同
- 2024区块链技术研发与商业应用合同
- 2024年度环保设备采购与维护服务合同
- 2024年技术服务与技术授权协议
- 2024核算会计工作计划(3篇)
- 美容顾问的年终总结范文(7篇)
- 创卫工作计划范文7篇
- 2024年抹灰工程劳务分包合同
- 2024年应急电源调度合同
- 【工商企业管理专业实操实训报告2600字(论文)】
- HJ 636-2012 水质 总氮的测定 碱性过硫酸钾消解紫外分光光度法
- 主播薪资核算方案
- 机电仪运维中心巡检工作提升方案
- 10以内口算题每页50道
- 大学生职业生涯规划与就业指导(高校学生学习职业生涯规划与就业指导课程)全套教学课件
- 《道德与法治》三年级学情分析
- 校园禁烟承诺书(12篇)
- 国家开放大学《计算机网络》课程实验报告实验六-计算机网络综合性实-
- 学校教育统计工作计划方案
- 售后服务方案及运维方案
评论
0/150
提交评论