1、第十一章 JAVA 网络编程11.1 Java 的网络通信功能11.1.1 JAVA 的网络支持JAVA 作为“网络上的世界语” ,具有独特的网络优势与网络功能。为了进行网络编程,JAVA 提供了一个 包,将该工具包与 java 中的输入/输出流相结合,就可以做到从网络上读取文件、数据或向网络写文件或数据时,可以象在本地磁盘上读写文件或数据一样容易和方便。Java 提 供 了 大 量 的 类 以 满 足 网 络 化 、 多 线 程 、 面 向 对 象系统 的 需 要 。 1. 语 言 包 提 供 的 支 持 包 括 字 符 串 处 理 、 多 线 程 处 理 、例外 处 理 、 数 学 函数
2、 处 理 等 ,可 以 用 它 简 单 地 实 现 Java 程 序的 运 行 平 台 。 2. 实 用 程 序 包 提 供 的 支 持 包 括 哈 希 表 、 堆 栈 、 可 变 数组、 时 间 和 日 期 等。 3. 输 入 输 出 包 用 统 一 的 “流 “模 型 来 实 现 所 有 格式 的 I/O,包括 文 件 系 统 、 网 络、 输 入 /出 设 备 等 。 4. 低 级 网 络 包 用 于 实 现 URL、Socket、数据报等网络编 程方法 。 5. 抽 象 图 形 用 户 接 口 包 实 现 了 不 同 平 台 的 计 算 机 的 图形用 户 接 口 部 件 ,包括 窗
3、口 、 菜 单 、 滚 动 条 、 对 话 框 等 ,使得 Java 可 以 移 植 到 不 同平 台 的 机 器 。 6. 网 络 包 支 持 Internet 的 TCP/IP 协 议 ,提 供 了 与 Internet 的 接 口。它 支 持 URL 连 接,WWW 的 即 时 访 问 ,并 且 简 化 了 用 户 /服 务 器 模型 的 程 序 设 计 。在 JAVA 网络编程过程中,大量地使用到输入输出流,即 JAVA.IO 包中的两个基本流:InputStream 和 OutputStream。InputStream 继承了 Object 类,它有六个直属的子类,其中之一的Filt
4、erInputStream 是一个抽象类,并有四个后代,如图 11-1 所示。类似地,OutputStream 继承了 Object 类,它有四个直属的子类,其中之一的FilterOutputStream 是一个抽象类,并有三个子类,如图 11-2 所示。11.1.2 InetAddress 类的使用在进行网络通信时,必须指定通信地址,在 JAVA 中由 InetAddress 类来完成该功能。类 InetAddress 可以用于标识网络上的硬件资源,它提供了一系列方法以描述、获取及使用网络资源。InetAddress 类没有构造函数,因此不能用 new 来构造一个 InetAddress 实
5、例。通常是用它提供的静态方法来获取:public static InetAddress getByName(String host) :host 可以是一个机器名,也可以是一个形如“%d.%d.%d.%d”的 IP 地址或一个 DSN 域名。public static InetAddress getLocalHost() public static InetAddress getAllByName(String host)这三个方法通常会产生 UnknownHostException 例外,应在程序中捕获处理。InetAddress 类的主要方法包括:1 GetHostName()返回该地址的
6、主机名。如果主机名为 null,那么当前地址指向当地机器的任一可得网络地FileInputStreamPipeInputStreamFilterInputStreamByteArrayInputStreamSequenceInputStreamStringBufferInputStreamDataInputStreamBufferedInputStreamLineNumberInputStreamPushBackInputStreamInputStream图 11-1 InputStream 类的继承树PipeOutputStreamFilterOutputStreamByteArrayOut
7、putStreamFileOutputStreamDataOutputStreamBufferedOutputStreamPrintStreamOutputStream图 11-2 OutputStream 类的继承树址。返回值:类型为 string2 GetAddress()以网络地址顺序来返回 IP 地址返回值:存在 byte型的字节数组中,其中,最高序字节位于标值为 0 的元素中。3 GetHostAddress()以“%d%d%d%d”的形式返回 IP 地址串。返回值:类型为 string4 HashCode()返回该 InetAddress 对象的散列码。返回值:类型为 int5 E
8、quals(Object obj)将当前对象与指定对象进行比较。返回值:true 相同false 不相同6 ToString()将该 InetAddress 对象以字符串的形式表示出来。返回值:类型为 string 的实体对象。7 GetByName(string host)这是一个 synchronized 的类方法,该方法用于返回指定主机的网络地址。如果主机名为null,则返回当地机器的默认地址。为了加速对地址的访问,使用了一个当地 cashe.如果地址未知,则会发生 unknowHostException 例外。参数:host 指定的主机。返回值:类型为 InetAddress8 Get
9、AllByName(string host)返回指定主机名的所有 InetAddress 对象,这是一个 synchrozed 类方法,若无法决定主机名,则会发生 unknowHostException 例外。参数:host 指定的主机。返回值:存放于 InetAddress数组中。9 GetLocalHost()用于返回当地主机的 InetAddress 对象。如果无法决定主机名,则会发生unknowHostException 例外。利用 InetAddress 类提供的方法,可以开发一些应用程序。例 1:获取本机的 IP 地址import .*;public class getLocalH
10、ostTestpublic static void main(String arg)InetAddress myIP=null;try myIP=InetAddress.getLocalHost();catch(UnknownHostException e)System.out.println(myIP);执行结果如下图所示:例 2:java 根据域名自动到 DNS 上查找 IP 地址import .*;public class getIPpublic static void main(String args)InetAddress swjtu=null;tryswjtu=InetAddres
11、s.getByName(““);catch(UnknownHostException e) System.out.println(swjtu);执行结果如图所示:11.2 JAVA 中的网络编程方法JAVA 中的网络编程可在三个层面上进行: URL 层:这是最高级层面。可以利用 URL 直接进行 Internet 上的资源访问和数据传输。 Socket 层:这是传统网络编程经常采用的方式。通过在应用程序间建立 Socket 套接字连接,然后在连接之上进行数据通信。Client/Server 结构应用程序通常采用这种面向连接的模式。 Datagram 数据流层:这是最低级层面。是无连接的通信方式
12、。 为了实现上述的网络通信功能,JAVA 提供了相应的类: .URL 类和 .URLConnection 类使得编程者能很方便地利用 URL在 Internet 上进行网络通信。 包的 Socket 类(客户端)和 ServerSocket 类(服务器端)提供了用TCP/IP 套接字来编写 C/S 应用程序的方法。 包的 DatagramServer 和 DatagramPacket 类用于实现 UDP 通信。 11.3 JAVA URL 网络编程.URL 类和 .URLConnection 类使得编程者能很方便地利用 URL在 Internet 上进行网络通信。11.3.1 URL 概念
13、 URL(Uniform Resource Locator)是统一资源定位器的简称,是用来标识 Internet上的资源的,通过 URL 可以访问 Internet 上相应的文件和其他资源。URL 指明了 取得资源采用的协议和资源地址 。 URL 格式:协议名:/资源名 协议名:指明获取资源所用的传输协议,如:http、ftp、gopher、 new、mailto、file 等。 资源名:是资源的完整地址,包括主机 IP 地址( 或主机域名 )、端口号、完整文件名、HTML 文件中 参考位置 等。 下面是几个 URL 的例子: http:/ 一个完整的 URL 如下: http: /:80/h
14、ome/white_paper.html#intro_1 协议 主机域名(IP 地址) 端口号 目录 文件名 HTML 参考点 其中,传输协议:说明访问资源时使用的网络协议。 主机名称( host name ):资源所在的主机的名称( IP 地址) 。 文件名(file name) :资源在机器上的完整名字。这里的文件名并不是简单的名字,它要包括文件的完整的路径名,这样我们才能直接通过文件名访问到一个文 件。 端口号( port number):连接时所使用的服务器端口号。省略时表示标准端口号,如 http:80,telnet:23 等 。 参考点( reference ):资源中的特定位置,
15、用来标识一个文件中特定的偏移位置。通过参考点我们可以对一个文件中感兴趣的部分创建 URL 对象。11.3.2 URL 类 URL 类定义了一个 WWW 的统一资源定位器和可以对其进行的一些操作。由 URL 类生成的对象指向 WWW 资源 (如 WEB 页、文本文件、图形图象文件、音频视频文件等等)。建立 URL 对象后就可使用通用的格式取得 URL 的各个部分的信息和获取 URL 内容。 一、URL 构造方法 URL 共有 6 个构造方法:(1) URL(String spec) 简单地用一个字符串生成 URL 对象,例如:URL url0=new URL(“ http:/:80/YFjava
16、/java7.html “);(2) URL(String protocol,String host,String file)由用户分开指定 URL 各个部分、但采用缺省端口构成 URL 对象,例如: URL url1=new URL(“ http“ ,“ “ ,“/YFjava/java7.html“); (3) URL(String protocol,String host,int port,String file); 由用户分开指定 URL 各个部分构成 URL 对象,例如: URL url2=new URL(“http“,““,80, “/YFjava/java7.html“); 注意
17、:2、3 构造方法不能构造含有“参考点”的 URL 地址。(4) URL(URL context,String spec) 构造相对 URL 对象,如:URL base1=new URL(“http:/ :80/ YFjava/“ ); URL url3=new URL( base1,“ java7.html“);(5)URL(URL context, String spec, URLStreamHandler handler)(6)URL(String protocol, String host, int port, String file, URLStreamHandler handler
18、)二、 异常处理 URL 类的构造方法都可能发生 MalformedURLException 非运行时异常,因此生成URL 对象时,必须对这一异常进行处理。如: try URL myURL=new URL(“http:/ catch (MalformedURLException e) System.out.println(“MalformedURLException:“+e); 11.3.3 通过 URL 访问 WWW 一、获取 URL 属性通过 URL 类的方法可以获得 URL 的属性。String getProtocol()方法:获取 URL 中的传输协议。String getHost()
19、方法:获取 URL 中的主机名称。int getPort():获取 URL 中的端口号,如果一个 URL 地址没有端口号,返回值为-1。 String getFile():返回目录文件名(路径名) 。 String getRef():获取 URL 中的参考点,如果一个 URL 地址没有参考点,返回值为null。String toExternalForm():将 URL 地址转换成字符串。String toString() :将 URL 地址转换成字符串。boolean sameFile(URL other):比较两个 URL 是否相同。实例一:获取 URL 属性的 URLTest0.java命
20、令行格式:java URLTest0 http:/ 本例仅仅是获取 URL 属性,因此在没有建立连接的情况下就可运行。import .*;public class URLTest0public static void main(String args)if(args.length=1)try URL url=new URL(args0); /*创建 URL 对象*/System.out.println(“URL: “+url.toExternalForm()+“n“+“File: “+url.getFile()+“n“+“Host: “+url.getHost()+“n“+“Port: “+u
21、rl.getPort()+“n“+“Protocol:“+url.getProtocol()+“n“);catch(MalformedURLException e)System.out.println(“Bad URL.“);elseSystem.out.println(“Usage:URLTest0 URL“);执行结果如下图所示 :二、获取 URL 内容可以通过 URL 类提供的三个主要方法来访问它指向的资源(获取 URL 内容): 用 URL 类的 getContent()方法直接获取 URL 内容。 用 URL 类的 openConnection()获得与 URL 的 URLConne
22、ction 连接。 用 openStream()方法得到 InputStream 流。实际上,类 URL 的方法 openStream()是通过 URLConnection 来实现的,它等价于 openConnection().getInputStream()。(1)利用 getContent()方法建立一个与指定资源的连接并可直接获取 URL 指定的资源,它会试图决定流的 MIME类型并将流转换为相应的 Java Object。例如,如果我们创建了一个指向 GIF 格式图片的 URL,getContent() 方法将识别流的类型为“image/gif“或“image/jpeg”,并返回 Im
23、age 类的一个实例。该 Image 对象包含该 GIF 图片的一个拷贝。我们可以通过 getContent()方法将资源取到一个 Java 对象中,然后进行相应处理。实例二:通过 getContent()方法下载一图象文件并在 Frame 中显示。/文件名 URLTest2.javaimport .*;import java.io.*;import java.awt.*;import java.awt.image.*;import java.awt.event.*;public class URLTest2 extends Frame private Image img;public voi
24、d paint(Graphics g) g.drawImage(img,20,20,this);public void processWindowEvent(WindowEvent e) super.processWindowEvent(e);if(e.getID()=WindowEvent.WINDOW_CLOSING)System.exit(0);public static void main(String args) throws MalformedURLException, IOException if(args.length!=1) / 检查用户是否提供了程序所需的命令行参数Syst
25、em.out.println(“Usage:java URLTest2“);System.exit(-1);URL url=new URL(args0); / 创建 URL 对象URLTest2 urlt= new URLTest2();urlt.img=urlt.createImage(ImageProducer)url.getContent();urlt.enableEvents(AWTEvent.WINDOW_EVENT_MASK);urlt.setSize(600,400);urlt.setVisible(true);当把该 java 文件保存到服务器的 doc 目录下,输入的命令行参
26、数是:http:/127.0.0.1:8080/1.png执行结果:(2)利用 openConnection()方法在创建 URL 对象之后,可以调用 URL 类中的 openConnection()函数,在你的机器和对方主机之间建立通信连接。例如,可以采用下列的方法连上 yahoo 搜索引擎:tryURL yahoo=new URL(http:/ (malformedURLException e) /构造 URL 可能产生的异常catch (IOException e) /I/O 操作可能产生的异常URLConnection 对象提供了许多可用于网络读写的函数,它可与程序和网络的另一端进行信
27、息交互,而不象 URL 对象只能用来读数据。(3)利用 openStream()方法 建立连接 URL 后,可以调用 URL 类中的 openStream()函数来打开一个流,从流中可读取 URL 中的内容。OpenStream()函数返回一个 java.io.InputStream 流对象,可从中读取数据。 如:try URL url1=new URL(getCodeBase(),“readme.txt“) ;InputStream in=url1.openStream();int ch;while(ch=in.read()!=-1)System.out.print(char)ch);catch(Exception e) /意外处理e.printStackTrace();实例三:在本机上打开一个输入流,从中读取数据,并显示在屏幕上。 运行格式: java URLTest3 http:/127.0.0.1:8080/URLTest3.java/文件名是 URLTest3.javaimport .*;import java.io.*;class URLTest3public static void main(String args)