第14章Java网络编程.ppt

上传人:本田雅阁 文档编号:2510123 上传时间:2019-04-04 格式:PPT 页数:43 大小:1.35MB
返回 下载 相关 举报
第14章Java网络编程.ppt_第1页
第1页 / 共43页
第14章Java网络编程.ppt_第2页
第2页 / 共43页
第14章Java网络编程.ppt_第3页
第3页 / 共43页
亲,该文档总共43页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《第14章Java网络编程.ppt》由会员分享,可在线阅读,更多相关《第14章Java网络编程.ppt(43页珍藏版)》请在三一文库上搜索。

1、第14章 Java网络编程 14.1 URL类 URL类是包中的一个重要的类,URL的实例封装 着一个统一资源定位符(Uniform Resource Locator) ,使用URL创建对象的应用程序称作客户端程序。一个 URL对象封装着着一个具体的资源的引用,表明客户要访 问这个URL中的资源,客户利用URL对象可以获取URL中 的资源。一个URL对象通常包含最基本的三部分信息:协 议、地址、资源。协议必须是URL对象所在的Java虚拟机 支持的协议,许多协议并不为我们所常用,而常用的Http 、Ftp、File协议都是虚拟机支持的协议;地址必须是能连 接的有效IP地址或域名;资源可以是主机

2、上的任何一个文 件 14.1.1 URL的构造方法 URL类通常使用如下的构造方法创建一个URL对 象: public URL(String spec) throws MalformedURLException 该构造方法使用字符串初始化一个URL对象 另一个常用的构造方法是: public URL(String protocol, String host,String file) throws MalformedURLException 该构造方法构造使用的协议、地址和资源分别由 参数protocol、host和file指定 14.1.2 读取URL中的资源 URL对象调用InputStre

3、am openStream() 方法 可以返回一个输入流,该输入流指向URL对象所 包含的资源。通过该输入流可以将服务器上的资 源信息读入到客户端。URL对象调用 InputStream openStream() 方法可以返回一个输入流,该输入流指向URL对 象所包含的资源。通过该输入流可以将服务器上 的资源读入到客户端 14.2 InetAdress类 14.2.1 地址的表示 Internet上的主机有两种方式表示地址: 1域名 例如, 2IP 地址 例如,202.108.35.210 包中的InetAddress类对象含有一个 Internet主机地址的域名和IP地址: 14.2.2

4、获取地址 1获取Internet上主机的地址 可以使用InetAddress类的静态方法: getByName(String s); 将一个域名或IP地址传递给该方法的参数s,获得 一个InetAddress对象,该对象含有主机地址的 域名和IP地址,该对象用如下格式表示它包含的 信息: 另外,InetAddress类中还有两个实例方法: public String getHostName() 获取 InetAddress对象所含的域名。 public String getHostAddress() 获取 InetAddress对象所含的IP地址。 2获取本地机的地址 我们可以使用InetA

5、ddress类的静态方法: getLocalHost()获得一个InetAddress对象,该 对象含有本地机的域名和IP地址。 14.3 套接字 14.3.1 套接字 网络通信使用IP地址标识Internet上的计算机,使用端口 号标识服务器上的进程(程序)。也就是说,如果服务器 上的一个程序不占用一个端口号,用户程序就无法找到它 ,就无法和该程序交互信息。端口号被规定为一个16位的 065535之间的整数,其中,01023被预先定义的服务 通信占用(如telnet占用端口23,http占用端口80等), 除非我们需要访问这些特定服务,否则,就应该使用 102465535这些端口中的某一个进

6、行通信,以免发生端 口冲突 当两个程序需要通信时,它们可以通过使用Socket类建立 套接字对象并连接在一起 14.3.2 客户端套接字 客户端的程序使用Socket类建立负责连接到服务 器的套接字对象。 Socket的构造方法是:Socket(String host,int port),参数host是服务器的IP地址,port是一个 端口号。建立套接字对象可能发生IOException 异常,因此应象下面那样建立连接到服务器的套 接字对象: try Socket mysocket=new Socket(“http:/192.168.0.78“,2010); catch(IOException

7、 e) 14.3.3 ServerSocket对象与服务器端 套接字 为了能使客户成功地连接到服务器,服务器必须建立一个 ServerSocket对象,该对象通过将客户端的套接字对象和 服务器端的一个套接字对象连接起来,从而达到连接的目 的。 ServerSocket的构造方法是:ServerSocket(int port), port是一个端口号。port必须和客户呼叫的端口号相同。 当建立ServerSocket对象时可能发生IOException异常, 因此应象下面那样建立ServerSocket对象: try ServerSocket serverForClient = new Ser

8、verSocket(2010); catch(IOException e) 当服务器的ServerSocket对象serverForClient建 立后,就可以使用方法accept()将客户的套接字 和服务器端的套接字连接起来,代码如下所示: try Socket sc = serverForClient.accept(); catch(IOException e) 客户端的Socket 输入流 输出流 服务器端Socket 输出流 输入流 图14.2 套接字连接示意图 互相连接 互相连接 连接建立后,服务器端的套接字对象调用 getInetAddress()方法可以获取一个InetAddes

9、s 对象,该对象含有客户端的IP地址和域名,同样 ,客户端的套接字对象调用getInetAddress()方 法可以获取一个InetAddess对象,该对象含有服 务器端的IP地址和域名。 双方通信完毕后,套接字应使用close()方法关闭 套接字连接 14.3.4 使用多线程技术 从套接字连接中读取数据与从文件中读取数据有 着很大的不同。尽管二者都是输入流,但从文件 中读取数据时,所有的数据都已经在文件中了, 而使用套接字连接时,可能在另一端数据发送出 来之前,就已经开始试着读取了,这时,就会堵 塞本线程,直到该读取方法成功读取到信息,本 线程才继续执行后续的操作。因此,服务器端收 到一个客

10、户的套接字后,就应该启动一个专门为 该客户服务的线程 服务器程序 客户1的线程客户1 客户2的线程客户2 客户3的线程客户3 图14.5 具有多线程的服务器端程序 可以使用Socket类的不带参数的构造方法 Socket()创建一个套接字对象,该对象再调用 public void connect(SocketAddress endpoint) throws IOException 请求和参数SocketAddress指定地址的服务器端 的套接字建立连接。为了使用connect方法,可 以使用SocketAddress的子类: InetSocketAddress创建一个对象, InetSocke

11、tAddress的构造方法是: public InetSocketAddress(InetAddress addr, int port) 14.4 UDP数据报 基于UDP的通信和基于TCP的通信不同,基于 UDP的信息传递更快,但不提供可靠性保证。也 就是说,数据在传输时,用户无法知道数据能否 正确到达目的地主机,也不能确定数据到达目的 地的顺序是否和发送的顺序相同。可以把UDP通 信比作生活中的邮递信件,我们不能肯定所发的 信件就一定能够到达目的地,也不能肯定到达的 顺序是发出时的顺序,可能因为某种原因导致后 发出的先到达。 基于UDP通信的基本模式是: 将数据打包,称为数据包(好比将信件

12、装入信封 一样),然后将数据包发往目的地。 接受别人发来的数据包(好比接收信封一样), 然后查看数据包中的内容。 14.4.1 发送数据包 1用DatagramPacket类将数据打包,即用 DatagramPacket类创建一个对象,称为数据包 。用DatagramPacket的以下两个构造方法创建 待发送的数据包: DatagramPacket(byte data,int length,InetAddtress address,int port): 使用该构造方法创建的数据包对象具有下列两个性质: 含有data数组指定的数据。 该数据包将发送到地址是address、端口号是port的主机

13、上。 我们称address是它的目标地址、port是这个数据包的目 标端口。 DatagramPack(byte data,int offset,int length,InetAddtress address,int port) 使用该构造方法创建的数据包对象含有数组data中从 offset开始后的length个字节,该数据包将发送到地址是 address,端口号是port的主机上。 2用DatagramSocket类的不带参数的构造方法 :DatagramSocket()创建一个对象,该对象负责 发送数据包。例如: DatagramSocket mail_out=new DatagramS

14、ocket(); mail_out.send(data_pack); 14.4.2 接收数据包 首先用DatagramSocket的另一个构造方法: DatagramSocket(int port) 创建一个对象,其中 的参数必须和待接收的数据包的端口号相同。例 如,如果发送方发送的数据包的端口是5666,那 么如下创建DatagramSocket对象: DatagramSocket mail_in=new DatagramSocket(5666); 然后对象mail_in使用方法receive(DatagramPacket pack)接受数据包。该方法有一个数据包参数pack,方法 rece

15、ive把收到的数据包传递给该参数。因此我们必须预备 一个数据包以便收取数据包。这时需使用 DatagramPack 类的另外一个构造方法:DatagramPack(byte data,int length)创建一个数据包,用于接收数据包,例如: byte data=new byte100; int length=90; DatagramPacket pack=new DatagramPacket(data,length); mail_in.receive(pack); 该数据包pack将接收长度是length字节的数据放入data 。 14.5 广播数据报 计算机使用IP地址和端口来区分其位置

16、和进程, 但有一类地址非常特殊,称作D类地址,D类地址 不是用来代表位置的,即在网络上不能使用D类 地址去查找计算机。 D类地址好像生活中的社团组织,不同地理位置 的人可以加入相同的组织,继而可以享有组织内 部的通信权利。 Internet的地址是a.b.c.d的形式。该地址的一部 分代表用户自己的主机,而另一部分代表用户所 在的网络。当a小于128,那么b.c.d就用来表示 主机,这类地址称做A类地址。如果a大于等于 128并且小于192,则a.b表示网络地址,而c.d 表示主机地址,这类地址称做B类地址。如果a大 于等于192,则网络地址是a.b.c,d表示主机地 址,这类地址称做C类地址

17、。 224.0.0.0224.255.255.255是保留地址,称 作D类地址 要广播或接收广播的主机都必须加入到同一个D 类地址。一个D类地址也称做一个组播地址,D类 地址并不代表某个特定主机的位置,一个具有A 、B或C类地址的主机要广播数据或接收广播,都 必须加入到同一个D类地址。 14.6 Java 远程调用(RMI) RMI(Remote Method Invocation)是一种分 布式技术,使用RMI可以让一个虚拟机上的应用 程序请求调用位于网络上另一处的虚拟机上的对 象方法。习惯上称发出调用请求的虚拟机为(本 地)客户机,称接受并执行请求的虚拟机为(远 程)服务器 14.6.1

18、远程对象及其代理 1远程对象 驻留在(远程)服务器上的对象是客户要请求的 对象,称作远程对象,即客户程序请求远程对象 调用方法,然后远程对象调用方法并返回必要的 结果。 2代理与存根(Stub) RMI不希望客户应用程序直接与远程对象打交道 ,代替地让用户程序和远程对象的代理打交道。 代理的特点是:它与远程对象实现了相同的接口 ,也就是说它与远程对象向用户公开了相同的方 法,当用户请求代理调用这样的方法时,如果代 理确认远程对象能调用相同的方法时,就把实际 的方法调用委派给远程对象。 RMI会帮助我们生成一个存根(Stub):一种特 殊的字节码,并让这个存根产生的对象为作为远 程对象的代理。代

19、理需要驻留在客户端,也就是 说,需要把RMI生成的存根(Stub)复制或下载 到客户端。因此,在RMI中,用户实际上是在和 远程对象的代理直接打交道,但用户并没有感觉 到他在和一个代理打交道,而是觉得自己就是在 和远程对象直接打交道。比如,用户想请求远程 对象调用某个方法,只需将向远程代理发出同样 的请求即可 (本地)客户机 远程 代理 客户应用程序 请求 (远程)服务器 远程 对象 请求 响应 图14.12 远程代理与远程对象 响应 3Remote接口 RMI为了标识一个对象是远程对象,即可以被客 户请求的对象,要求远程对象必须实现java.rmi 包中的Remote接口,也就是说只有实现该

20、接口 的类的实例才被RMI认为是一个远程对象。 Remote接口中没有方法,该接口仅仅起到一个 标识作用,因此,必须扩展Remote接口,以便 规定远程对象的那些方法是客户可以请求的方法 ,用户程序不必编写和远程代理的有关代码,只 需知道远程代理和远程对象实现了相同的接口 14.6.2 RMI的设计细节 为了叙述的方便,我们假设本地客户机存放有关 类的目录是D:Client;远程服务器的IP是 127.0.0.1,存放有关类的目录是D:Server。 1扩展Remote接口 定义一个接口是java.rmi包中Remote的子接口,即扩展Remote接 口。 以下是我们定义的Remote的子接口

21、是RemoteSubject。 RemoteSubject子接口中定义了计算面积的方法,即要求远程对象 为用户计算某种几何图形的面积。RemoteSubject的代码如下: RemoteSubject.java import java.rmi.*; public interface RemoteSubject extends Remote public void setHeight(double height) throws RemoteException; public void setWidth(double width) throws RemoteException; public do

22、uble getArea() throws RemoteException; 2远程对象 创建远程对象的类必须要实现Remote接口,RMI 使用Remote接口来标识远程对象,但是Remote 中没有方法,因此创建远程对象的类需要实现 Remote接口的一个子接口。另外,RMI为了让一 个对象成为远程对象还需要进行一些必要初始化 工作,因此,在编写创建远程对象的类时,可以 简单让该类是RMI提供的java.rmi.server包中的 UnicastRemoteObject类的子类即可。 以下是我们定义的创建远程对象的类:RemoteConcreteSubject,该类实现了上述 Remote

23、Subject接口(见本节上述标题1中的RemoteSubject接口),所创建的远程对象可以 计算矩形的面积,RemoteConcreteSubject的代码如下: RemoteConcreteSubject.java import java.rmi.*; import java.rmi.server.UnicastRemoteObject; public class RemoteConcreteSubject extends UnicastRemoteObject implements RemoteSubject double width,height; public RemoteConc

24、reteSubject() throws RemoteException public void setWidth(double width) throws RemoteException this.width=width; public void setHeight(double height) throws RemoteException this.height=height; public double getArea() throws RemoteException return width*height; 3. 存根(Stub)与代理 RMI负责产生存根(Stub Object),如

25、果创建远程对象 的字节码是RemoteConcreteSubject.class,那么存根( Stub)的字节码是RemoteConcreteSubject_Stub.class ,即后缀为“_Stub”。 RMI使用rmic命令生成存根: RemoteConcreteSubject_Stub.class。首先进入 D:Server目录,然后如下执行rmic命令: rmic RemoteConcreteSubject 执行过rmic命令将产生的存根: RemoteConcreteSubject_Stub.class 4.启动注册:rmiregistry 在远程服务器创建远程对象之前,RMI要求

26、远程服务器必 须首先启动注册:rmiregistry,只有启动了rmiregistry ,远程服务器才可以创建远程对象,并将该对象注册到 rmiregistry所管理的注册表中。 在远程服务器开启一个终端,比如在MS-DOS命令行窗口 进入D:Server目录,然后执行rimregistry命令:图 14.14 启动注册 rmiregistry 启动注册,也可以后台启动注册: start rmiregistry 5.启动远程对象服务 远程服务器启动注册rmiregistry后,远程服务器 就可以启动远程对象服务了,即编写程序来创建 和注册远程对象,并运行该程序。 远程服务器使用java.rmi

27、包中的Naming类调用其 类方法: rebind(String name, Remote obj) 绑定一个远程对象到rmiregistry所管理的注册表 中,该方法的name参数是URL格式,obj参数是 远程对象,将来客户端的代理会通过name 找到 远程对象obj。 BindRemoteObject.java import java.rmi.*; public class BindRemoteObject public static void main(String args) try RemoteConcreteSubject remoteObject=new RemoteConcr

28、eteSubject(); Naming.rebind(“rmi:/127.0.0.1/rect“,remoteObject); System.out.println(“be ready for client server.“); catch(Exception exp) System.out.println(exp); 运行客户端程序 远程服务器启动远程对象服务后,客户端就可以运行有关 程序,访问使用远程对象。 客户端使用java.rmi包中的Naming类调用其类方法: lookup(String name) 返回一个远程对象的代理,即使用存根(Stub)产生一个 和远程对象具有同样接口的对象。Lookup(String name) 方法中的name参数的取值必须是远程对象注册的name, 比如:“rmi:/127.0.0.1/rect“。 客户程序可以像使用远程对象一样来使用 lookup(String name)方法返回的远程代理。比如,下面 的客户应用程序ClientApplication中的 Naming.lookup(“rmi:/127.0.0.1/rect“); 返回一个实现了RemoteSubject接口的远程代理

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1