1.创建远程接口
2.实现远程接口
3.把远程接口绑定到远程服务器上,并启动远程服务器
4.创建客户端,查找远程接口,使用远程接口。
package com.rmi.server;
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
* 远程接口
* 必须继承Remote接口,标识所包含的方法可以从非本地虚拟机上调用的接口,Remote
* 接口本省不含任何方法
* 远程接口方法必须抛出RemoteException
* @author al
*
*/
public interface DoHousework extends Remote{
public void cooking() throws RemoteException;
public void cleanning() throws RemoteException;
}
package com.rmi.server;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
/**
* 远程方法接口的实现类
* UnicastRemoteObject类的构造函数抛出RemoteException,
* 故继承类不能使用默认构造函数,继承类的构造函数也必须抛出RemoteException,
* 由于方法参数和返回值最终都将在网络上传输,所以必须是可序列化及实现Serializable接口
*
*继承UnicastRemoteObject的好处
* RemoteServer继承RemoteObject,UnicastRemoteObject继承RemoteServer,
* 首先RemoteObjectSerializable, Remote这两个接口RemoteObject的真正作用在于,他重写了Object的hashCode、equals、和toString方法,重写hashCode方法使得远程对象可以存放在Hashtable等一些哈希结果的集合中,重写equals方法使得远程对象可以进行比较,而重写后的toString方法返回远程对象的描述串。该类还实现专门的(私用)方法writeObject 和方法readObject,用于系列化与反系列化
* RemoteServer(abstract)则提供了一些对调试非常有用的方法,它一共有3个方法:
* static String getClientHost():返回一个客户机主机的字符串表示形式,用于在当前线程中正在处理的远程方法调用。
* static PrintStream getLog():返回用于 RMI 调用日志的流。
* static void setLog(OutputStream out):将 RMI 调用记录到输出流 out 中。
* 远程对象都 继承UnicastRemoteObject类,UnicastRemoteObject 类提供远程对象所需的基本行为。在这个类中提供了支持创建和导出远程对象的一系列方法,一个对象继承UnicastRemoteObject它将获得以下特性:
* A、对这种对象的引用至多仅在创建该远程对象的进程生命期内有效
* B、使得远程对象既有使用TCP协议通信的能力(Socket)
* C、对于客户端与服务器的调用、传参、返回值等操作使用流的方式来处理
*/
public class DoHouseworkImpl extends UnicastRemoteObject implements DoHousework {
protected DoHouseworkImpl() throws RemoteException {
super();
// TODO Auto-generated constructor stub
}
@Override
public void cooking() {
System.out.println("我正在做饭.................");
}
@Override
public void cleanning() {
System.out.println("我正在打扫卫生...................");
}
}
package com.rmi.server;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
/**
* java.rmi.registry.LocateRegistry类提供了一系列的方法用于创建、
* 获取Registry实例的方法;在Registry接口中,定义了一系列的方法,
* 用于操作远程对象包括:绑定对象(bind)、获取对象(lookup)、
* 重写绑定(rebind)、解除绑定(unbind)
* 和返回注册表绑定列表(list)方法(也可以使用java.rmi.Naming来操作)。
* @author al
*
*/
public class DoHouseworkServer {
public static void main(String[] args) throws Exception {
System.out.println("启动远程服务................");
try {
DoHousework doHousework = new DoHouseworkImpl();
//创建并导出接受指定port请求的本地主机上的Registry实例。
Registry registry = LocateRegistry.createRegistry(1099);
//registry.bind("doHousework", doHousework);
Naming.rebind("rmi://localhost:1099/doHousework", doHousework);
System.out.println("远程服务启动成功........................");
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package com.rmi.server;
import java.net.MalformedURLException;
import java.rmi.AccessException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
public class DoHouseworkClient {
public static void main(String[] args) throws Exception {
//获取远程对象
DoHousework doHousework =(DoHousework) LocateRegistry.getRegistry("127.0.0.1", 1099).lookup("doHousework");
//DoHousework doHousework = (DoHousework) Naming.lookup("rmi://127.0.0.1:12123/doHousework");
System.out.println("发出做饭指令.................");
doHousework.cooking();
System.out.println("做饭完成.................");
System.out.println("休息.................");
Thread.sleep(3333);
System.out.println("发出打扫卫生指令.................");
doHousework.cleanning();
System.out.println("打扫卫生完成.................");
}
}