




已阅读5页,还剩66页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第15章 网络编程,15.1 URL通信 15.2 Socket通信 15.3 UDP通信,15.1 URL通信 URL(Uniform Resource Locator,统一资源定位器)表示Internet/Intranet上的资源位置。这些资源可以是一个文件、一个目录或一个对象。当我们使用浏览器浏览网络上的资源时,首先需要键入URL地址,才可以访问相应的主页。例如: :80/index.html /index.html file:/c:/ABC/xx.java 每个完整的URL由四部分组成,这四部分的划分及其含义如表15.1中所示。,表15.1 URL地址的组成,一般的通信协议都已经规定好了开始联络时的通信端口,例如,HTTP协议的缺省端口号是80,FTP协议的缺省端口号是21等。URL使用协议的缺省端口号时,可以不写出缺省端口号。所以,一般的URL地址只包含传输协议、主机名和文件名就足够了。 网络通信中,我们常常会碰到地址(Address)和端口(Port)的问题。两个程序之间只有在地址和端口方面都达成一致时,才能建立连接。这与我们寄信要有地址、打电话要有电话号码一样。两个远方程序建立连接时,首先需要知道对方的地址或主机名,其次是端口号。地址主要用来区分计算机,网络中的各个计算机,而端口的定义可以理解为扩展的号码,具备一个地址的计算机可以通过不同的端口来与其他计算机进行通信。 在TCP协议中,端口被规定为一个在065 535之间的16位的整数。其中,01023被预先定义的服务通信占用(如FTP协议的端口号是21,HTTP协议的端口号为80等)。除非我们需要访问这些特定服务,否则就应该使用102465 535这些端口中的某一个来进行通信,以免发生端口的冲突。,15.1.1 URL类 要使用URL进行网络编程,就必须创建URL对象。创建URL对象要使用软件包中提供的.URL类的构造方法。 1创建URL对象 URL类提供的用于创建URL对象的构造方法有4个: (1) URL(String spec)方法。根据 String 表示形式创建URL对象。例如: URL file=new URL(“/index.html“); 这种以完整的URL创建的URL对象称为绝对URL,该对象包含了访问该URL所需要的全部信息。,(2) URL(String protocol,String host,String file)方法。根据指定的protocol、host、port号和file创建URL对象。其中的protocol为协议名,host为主机名,file为文件名,端口号使用缺省值。例如: “http“,““,“index.html“ (3) URL(String protocol,String host,String port,String file)方法。这个构造方法与构造方法(2)相比,增加了1个指定端口号的参数。,(4) URL(URL context,String spec)方法。 通过在指定的上下文中用指定的处理程序对给定的spec进行解析来创建URL。例如: URL base=new URL(“file: /c:/ABC/xx.java“); URL gk=new URL(base,“gg.txt“); 中的URL对象gk是相对URL对象。javac在使用对象gk时会从对象base中查出文件gg.txt所在的位置:本地主机是c:/ABC/。对象gk指明的资源也就是file: /c:/ABC/gg.txt。 如果在程序中不访问xx.java,那么在创建base的构造方法中则略去xx.java。创建gg的方法不变,gg指明的资源仍不变。,2URL类的常用成员方法 创建URL对象后,可以使用.URL类的成员方法对创建的对象进行处理。.URL的常用成员方法如表15.2所示。,表15.2 URL类的常用成员方法,15.1.2 利用URL类访问网上资源示例程序 【示例程序C15_1.java】 获取某个URL地址的协议名、主机名、端口号和文件名。 package ch15; import .MalformedURLException; import .URL; public class C15_1 public static void main(String args ), URL MyURL=null; try MyURL=new URL(“/kb/docs/java/quickstart.html“); catch (MalformedURLException e) System.out.println(“MalformedURLException: “ + e); System.out.println(“URL String: “+MyURL.toString( ); /获取URL对象转换成字符串 System.out.println(“Protocol: “+MyURL.getProtocol( ); /获取协议名,System.out.println(“Host: ”+MyURL.getHost( ); /获取主机名 System.out.println(“Port: ”+MyURL.getPort( ); /获取端口号 System.out.println(“File: ”+MyURL.getFile( ); /获取文件名 该程序的运行结果如图15.1右下窗口所示。,图15.1 程序C15_1的运行结果,【示例程序C15_2.java】 使用URL类的openStream( )成员方法获取URL指定的网上信息。 package ch15; import java.io.*; import .MalformedURLException; import .URL; public class C15_2 public static void main(String args) String Str; InputStream st1;,/String ur=“/kb/docs/java/quickstart.html“; /获取远程网上的信息 String ur=“file:/E:/Java/ch15/src/ch15/C15_1.java“; /获取本地网上的信息 try URL MyURL=new URL(ur); st1=MyURL.openStream( ); InputStreamReader ins=new InputStreamReader(st1); BufferedReader in=new BufferedReader(ins); while(Str=in.readLine( )!= null) /从URL处获取信息并显示 System.out.println(Str); ,catch(MalformedURLException e) /创建URL对象可能产生的异常 System.out.println(“Cant get URL: “ ); catch (IOException e) System.out.println(“Error in I/O:“ + e.getMessage( ); 由于URL的openStream( )成员方法返回的是InputStream类的对象,因此只能通过read( )方法逐个字节地去读URL地址处的资源信息。这里利用BufferedReader对原始信息流进行了包装和处理,以提高I/O效率。运行的结果是显示出C15_1.java程序的内容。,15.1.3 使用URLConnection类访问网上资源 上面介绍的方法只能读取远程计算机节点的信息,如果希望在读取远程计算机节点的信息时还可向它写入信息,则需要使用软件包中的另一个类URLConnection。 1创建URLConnection类的对象 要创建URLConnection对象必须先创建一个URL对象,然后调用该对象的openConnection( )方法就可以返回一个对应其URL地址的URLConnection对象。例如: URL MyURL=new URL(“/index.html“); URLConnection con= MyURL.openConnection( );,2建立输入/输出数据流 读取或写入远程计算机节点的信息时,要建立输入或输出数据流。我们可以利用URLConnection类的成员方法getInputStream( )和getOutputStream( )来获取输入和输出数据流。例如,下面的两行语句用于建立输入数据流: InputStreamReader ins=new InputStreamReader(con.getInputStream( ); BufferedReader in=new BufferedReader(ins); 下面的语句行用于建立输出数据流: PrintStream out=new PrintStream(con.getOutputStream( );,3读取远程计算机节点的信息或向其写入信息 要读取远程计算机节点的信息,可调用in.readLine( )方法;向远程计算机节点写入信息时,可调用out.println(参数)方法。 URLConnection类是一个抽象类,它是代表程序与URL对象之间建立通信连接的所有类的超类,此类的一个实例可以用来读/写URL对象所代表的资源。出于安全性的考虑,Java程序只能对特定的URL进行写操作,这种URL就是服务器上的CGI(Common Gateway Interface,公共网关接口)程序。CGI是客户端浏览器与服务器进行通信的接口。下面通过一个例子来说明URLConnection类是如何使用的。,【示例程序C15_3.java】 使用URLConnection类从远程主机获取信息。 package ch15; import java.io.*; import .*; class C15_3 public static void main(String args) try String ur=“”; /获取远程网上的信息 / String ur=“file:/E:/Java/ch15/src/ch15/C15_1.java“ ; /获取本地网上的信息,URL MyURL=new URL(ur); String str; URLConnection con=MyURL.openConnection( ); InputStreamReader ins=new InputStreamReader(con.getInputStream( ); BufferedReader in=new BufferedReader(ins); while (str=in.readLine( )!=null) System.out.println(str); in.close( ); catch (MalformedURLException mfURLe) System.out.println(“MalformedURLException: “ + mfURLe); ,catch (IOException ioe) System.out.println(“IOException: ” + ioe); 该程序的运行结果如图15.2所示。,图15.2 程序C15_3的运行结果,15.2 Socket通信 Socket套接字是应用于网络通信中的重要机制。Socket最初是加利福尼亚大学Berkeley分校为UNIX操作系统开发的网络通信接口。随着UNIX操作系统的广泛使用,套接字成为当前最流行的网络通信应用程序接口之一。Java语言中采用的Socket通信是一种流式套接字通信,它采用TCP协议,通过提供面向连接的服务,实现客户/服务器之间双向、可靠的通信。包中的Socket类与ServerSocket类为流式套接字通信方式提供了充分的支持。,15.2.1 Socket的概念及通信机制 1Socket的概念 Socket称为“套接字”,也有人称为“插座”。在两台计算机上运行的两个程序之间有一个双向通信的链接点,而这个双向链路的每一端就称为一个Socket。,建立连接的两个程序分别称为客户端(Client)和服务器端(Server)。客户端程序申请连接,而服务器端程序监听所有的端口,判断是否有客户程序的服务请求。当客户程序请求和某个端口连接时,服务器程序就将“套接字”连接到该端口上,此时,服务器与客户程序就建立了一个专用的虚拟连接。客户程序可以向套接字写入请求,服务器程序处理请求并把处理结果通过套接字送回。通信结束时,再将所建的虚拟连接拆除。 一个客户程序只能连接服务器的一个端口,而一个服务器可以有若干个端口,不同的端口使用不同的端口号,并提供不同的服务。,2Socket通信机制 利用Socket进行网络通信分为三个步骤: (1) 建立Socket连接。在通信开始之前由通信双方确认身份,建立一条专用的虚拟连接通道。 (2) 数据通信。利用虚拟连接通道传送数据信息进行通信。 (3) 关闭。通信结束时将所建的虚拟连接拆除。 利用包中提供的Socket类和ServerSocket类及其方法,可完成上述操作。 Socket通信机制如图15.3所示。,图15.3 Socket通信机制,从图15.3中可以看到,服务器端的程序首先选择一个端口(port)注册,然后调用accept( )方法对此端口进行监听,等待其他程序的连接申请。如果客户端的程序申请和此端口连接,那么服务器端就利用accept( )方法来取得这个连接的Socket。 客户端的程序建立Socket时必须指定服务器的地址(host)和通信的端口号(port#),这个端口号必须与服务器端监听的端口号保持一致。,15.2.2 Socket类与 ServerSocket类 中提供了两个类,即ServerSocket类和Socket类,它们分别用于服务器端和客户端的Socket通信,进行网络通信的方法也都封装在这两个类中。 1ServerSocket对象与Socket对象的构造方法 Java在软件包中提供了ServerSocket类和Socket类对应的双向链接的服务器端和客户端,包含的主要构造方法如表15.3所示。,表15.3 ServerSocket类与Socket类的构造方法,2异常处理 在建立Socket对象的同时要进行异常处理,以便程序出错时能够及时做出响应。 (1) 服务器端:在建立ServerSocket类的对象和取得Socket类的对象时都要进行异常处理,例如下面语句中的try-catch语句。 ServerSocket server; Socket socket; try server=new ServerSocket(3561); catch(Exception e) System.out.println(“Error occurred:”+e); try socket=server.accept( ); catch(Exception e) System.out.println(“Error occurred:“+e);,(2) 客户端:在建立Socket类的对象时要进行异常处理,例如下面的try-catch语句。 Socket socket; try socket=new Socket(“Server Name”,3561); catch(Exception e) System.out.println(“Error occurred:“+e);,3获取输入/输出流 建立Socket连接后,就可以利用Socket类的两个方法getInputStream( )和getOutputStream( )分别获得向Socket类的对象读/写数据的输入/输出流。此时同样要进行异常处理,因此,通常将读/写数据的输入/输出流语句写在try-catch块中。例如: try InputStream ins=socket. getInputStream( ); OutputStream outs=socket. getOutputStream( ); catch(Exception e) System.out.println(“Error occurred:”+e); ,4读/写数据流 获取Socket类的对象的输入/输出流后,为了便于进行读/写,需要在这两个流对象的基础上建立易于操作的数据流对象,如InputStreamReader类、OutputStreamReader类或PrintStream类的对象。建立数据流的对象可采用如下语句: InputStreamReader in=new InputStreamReader(ins); BufferedReader inn=new BufferedReader(in); OutputStreamReader out=new InputStreamReader(outs); PrintStream out=new PrintStream(outs);,要读入一个字符串并将其长度写入输出流中,可以使用如下语句: String str=inn.readLine( ); Out.println(str.length( ); 5断开连接 无论是编写服务器程序还是客户端程序,通信结束时,必须断开连接并释放所占用的资源。Java提供了close( )方法来断开连接。 (1) 关闭Socket对象:socket.close( )。 (2) 关闭Server Socket对象:server.close( )。,15.2.3 流式Socket通信的示例程序 综合前面介绍的内容,这里给出几个示例程序作为总结。 【示例程序C15_4.java】 利用InetAddress类的对象来获取计算机主机信息。 package ch15; import .InetAddress; import .UnknownHostException; public class C15_4 public static void main(String args ), try if(args.length=1) /调用InetAddress类的静态方法,利用主机名创建对象 InetAddress ipa=InetAddress.getByName(args0); System.out.println(“Host name: “+ipa.getHostName( ); /获取主机名 System.out.println(“Host IP Address: “+ipa.toString( ); /获取IP地址 System.out.println(“Local Host: “+InetAddress.getLocalHost( ); else System.out.println(“输入一个主机名“); ,catch(UnknownHostException e) /创建InetAddress对象可能发生的异常 System.out.println(e.toString( ); /end of main( ) 运行时先在“ch15项目属性”对话框的“主类”后的文本框中输入“ch15.C15_4”,在“参数”后的文本框中输入“localhost”。然后,选择菜单栏中的“运行”“设置主项目” “ch15”,再单击菜单栏中的“运行”“清理并生成主项目”。最后,单击菜单栏中的“运行”“运行主项目”。程序运行后就会输出如下的运行结果:,Host name: localhost Host IP Address: localhost/ Local Host: EKKIVWZMWR79BJH/00 下面的示例程序C15_5.java和C15_6.java是一个完整的实现Socket通信的Java程序,分别为服务器端程序和客户端程序。在这个Socket通信程序中,服务器等待与客户端连接。当连接建立后,客户端向服务器端发送一条信息,服务器端收到后再向客户端发送一条信息。若客户端发送end结束消息传递,服务器端同意,则客户端拆除与服务器端的连接。,【示例程序C15_5.java】 Socket通信的服务器端程序。 package ch15; /Socke服务器端程序 import java.io.*; import .ServerSocket; import .Socket; public class C15_5 public static final int port=8000; public static void main(String args ), String str; try /在端口port注册服务 ServerSocket server=new ServerSocket(port); /创建当前线程的监听对象 System.out.println(“Started: “+server); Socket socket=server.accept( ); /负责C/S通信的Socket对象 System.out.println(“Socket: “+socket); /获得对应Socket的输入/输出流 InputStream fIn=socket.getInputStream( ); OutputStream fOut=socket.getOutputStream( ); /建立数据流,InputStreamReader isr=new InputStreamReader(fIn); BufferedReader in=new BufferedReader(isr); PrintStream out=new PrintStream(fOut); InputStreamReader userisr=new InputStreamReader(System.in); BufferedReader userin=new BufferedReader(userisr); while(true) System.out.println(“等待客户端的消息“); str=in.readLine( ); /读客户端传送的字符串 System.out.println(“客户端:“+str); /显示字符串 if(str.equals(“end“)break; /如果是end,则退出 System.out.print(“给客户端发送:“);,str=userin.readLine( ); out.println(str); /向客户端发送消息 if(str.equals(“end“)break; /while socket.close( ); server.close( ); /try catch(Exception e) System.out.println(“异常:“+e); ,【示例程序C15_6.java】 Socket通信的客户端程序。 package ch15; /Socket客户端程序 import java.io.*; import .InetAddress; import .Socket; public class C15_6 public static void main(String args) String str;,try InetAddress addr=InetAddress.getByName(““); /InetAddress addr=InetAddress.getByName(“8“); Socket socket=new Socket(addr,8000); System.out.println(“Socket: “+socket); /获得对应socket的输入/输出流 InputStream fIn=socket.getInputStream( ); OutputStream fOut=socket.getOutputStream( ); /建立数据流 InputStreamReader isr=new InputStreamReader(fIn); BufferedReader in=new BufferedReader(isr); PrintStream out=new PrintStream(fOut); InputStreamReader userisr=new InputStreamReader(System.in);,BufferedReader userin=new BufferedReader(userisr); while(true) System.out.print(“发送字符串:“); str=userin.readLine( ); /读取用户输入的字符串 out.println(str); /将字符串传给服务器端 if(str.equals(“end“)break; /如果是end,就退出 System.out.println(“等待服务器端消息“); str=in.readLine( ); /获取服务器发送的字符串 System.out.println(“服务器端字符:“+str); if(str.equals(“end“)break; ,socket.close( ); /关闭连接 catch(Exception e) System.out.println(“异常:”+e); 服务器端程序的运行情况如图15.4所示,客户端程序的运行情况如图15.5所示。,图15.4 服务器端程序输出窗口(ch15(run),图15.5 客户端程序输出窗口(ch15(#2),程序运行时,首先运行服务器程序C15_5.java,然后运行客户端程序C15_6.java建立两端的连接。输出窗口有两个,如图15.4和图15.5所示。先在客户端输出窗口给服务器发送信息,例如“How do you do!”,单击服务器窗口,当看到服务器收到信息并输出后,再给客户端发信息,例如“Find,thanks.”,客户端收到信息并输出后,再给服务器发送信息,直到客户端给服务器发“end”则结束通信。,15.2.4 URL通信与Socket通信的区别 URL通信与Socket通信都是面向连接的通信,它们的区别在于:Socket通信方式为主动等待客户端的服务请求方式,而URL通信方式为被动等待客户端的服务请求方式。 利用Socket进行通信时,在服务器端运行了一个Socket通信程序,不停地监听客户端的连接请求,当接到客户端请求后,马上建立连接并进行通信。利用URL进行通信时,在服务器端常驻有一个CGI程序,但它一直处于睡眠状态,只有当客户端的连接请求到达时它才被唤醒,然后建立连接并进行通信。,在Socket通信方式中,服务器端的程序可以打开多个线程与多个客户端进行通信,并且还可以通过服务器使各个客户端之间进行通信,这种方式适合于一些较复杂的通信。而在URL通信方式中,服务器端的程序只能与一个客户进行通信,这种方式比较适合于B/S通信模式。,15.3 UDP通信 URL和Socket通信是一种面向连接的流式套接字通信,采用的协议是TCP协议。在面向连接的通信中,通信的双方需要首先建立连接再进行通信,这需要占用资源与时间。但是在建立连接之后,双方就可以准确、同步、可靠地进行通信了。流式套接字通信在建立连接之后,可以通过流来进行大量的数据交换。TCP通信被广泛应用在文件传输、远程连接等需要可靠传输数据的领域。,UDP通信是一种无连接的数据报通信,采用的协议是数据报通信协议UDP(User Datagram Protocol)。按照这个协议,两个程序进行通信时不用建立连接;数据以独立的包为单位发送,包的容量不能太大;每个数据报需要有完整的收/发地址,可以随时进行收/发数据报,但不保证传送顺序和内容准确;数据报可能会被丢失、延误等。因此,UDP通信是不可靠的通信。由于UDP通信速度较快,因此常常被应用在某些要求实时交互,准确性要求不高,但传输速度要求较高的场合。 软件包中的类DatagramSocket和类DatagramPacket为实现UDP通信提供了支持。,15.3.1 UDP通信机制 利用UDP通信时,服务器端和客户端的通信过程如图15.6所示。服务器端的程序有一个线程不停地监听客户端发来的数据报,等待客户的请求。服务器只有通过客户发来的数据报中的信息才能得到客户端的地址及端口。,图15.6 UDP通信机制,15.3.2 DatagramSocket类 DatagramSocket类用于收/发数据报。其构造方法如下: (1) DatagramSocket( )方法。 (2) DatagramSocket(int port)方法。 (3) DatagramSocket(int port,InetAddress iaddr)方法。 其中,第一个构造方法将Socket连接到本机的任何一个可用的端口上;第二个将Socket连接到本机的port端口上;第三个则将Socket连接到指定地址的port端口上。 这里需要注意两点:一是规定端口时不要发生冲突;二是在调用构造方法时要进行异常处理。,receive( ) 和send( )是DatagramSocket类中用来实现数据报传送和接收的两个重要成员方法,其格式如下: (1) void receive(DatagramPacket packet)方法。 (2) void send(DatagramPacket packet)方法。 receive( )方法将使程序中的线程一直处于阻塞状态,直到从当前Socket中接收到信息后,将收到的信息存储在receive( )方法的参数packet的对象中。由于数据报是不可靠的通信,因此receive( )方法不一定能读到数据。为防止线程死掉,应该设置超时参数(timeout)。 send( )方法将DatagramPacket类的packet的对象中包含的数据报文发送到所指定的IP地址主机的指定端口。,15.3.3 DatagramPacket类 DatagramPacket类用来实现数据报通信,它的常用的两个构造方法,分别对应发送数据报和接收数据报: (1) DatagramPacket(byte sBuf ,int sLength,InetAddress iaddr,int iport)方法。这个构造方法用来创建发送数据报对象。其中,sBuf代表发送数据报的字节数组;sLength代表发送数据报的长度;iaddr代表发送数据报的目的地址,即接收者的IP地址;iport代表发送数据报的端口号。 (2) DatagramPacket(byte rBuf ,int rLength)方法。这个构造方法用来创建接收数据报对象。其中,rBuf代表接收数据报的字节数组;rLength代表接收数据报的长度,即读取的字节数。,15.3.4 UDP通信示例程序 下面通过建立一个简单的UDP服务器端和一个客户端的程序例子,讲述UDP的工作方式。在这个例子中,服务器端的程序只是不停地监听本机端口,一旦收到客户端发来的数据报,就回应一个简单的信息通知客户已经收到了数据报。客户端的程序向服务器发送一个包含一个字符串的数据报,同时告知服务器自己的地址及端口,以便服务器做出回应。,【示例程序C15_7.java】 UDP通信的服务器端程序。 package ch15; /UDP 服务器端程序 import .DatagramPacket; import .DatagramSocket; import .InetAddress; class UDPServerThread extends Thread /启动服务器线程的主程序 private DatagramPacket packet; private DatagramSocket socket; static final int sport=1777; UDPServerThread(), try /将Socket连接到本机的一个可用端口上 socket=new DatagramSocket(sport); System.out.println(“Listening on port:“+socket.getLocalPort(); catch(Exception e) System.out.println(“Error:“+e); public void run( ) /线程的主要操作 if(socket=null)return; while(true) try InetAddress address; int cport; byte buf1=new byte1000,buf2=new byte1000;,String s=“Your packet is received“; packet=new DatagramPacket(buf1,buf1.length); /生成一个接收数据报 socket.receive(packet); /接收数据报 String s1=new String(packet.getData( ); System.out.println(“Received from client: “+s1); /打印数据报的内容 address=packet.getAddress( ); cport=packet.getPort( ); /获得数据报的源地址与端口 buf2=s.getBytes( ); packet=new DatagramPacket(bu
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 17盼第2课时 同步 公开课一等奖创新教学设计 学习任务单 分层练习 听写
- 2026年中考语文文言文专练专题07古诗词鉴赏之对比阅读(讲义)(学生版+解析)
- 骨扫描结果解读
- 创业者法律培训课件
- 酒店客房月度工作汇报
- 炎症因子与组织再生-洞察及研究
- 创业健身房课件
- 果树整形修剪技术
- 勘察钻孔业务培训课件
- 儿童用药评估-洞察及研究
- 朝花夕拾鲁迅笔下的人物
- DB32-T 4638-2024 智能泵站技术导则
- 工程造价咨询服务方案(技术方案)
- 小学教师师德师风考核表
- 离婚网上申请书
- 保温楼面挤塑聚苯板XPS施工方案xps挤塑聚苯板保温施工方案
- 高中重点语法精讲康志强语法
- 管办分开的实践与体会-上海申康医院发展中心课件
- 结婚函调报告表
- 名著导读好书推荐读后感分享《绿野仙踪》PPT模(内容完整)板
- FZ/T 64087-2022木棉纤维絮片
评论
0/150
提交评论