day2—java_RMI
基础
Remote
一个interface(抽象方法),该interface中没有申明任何方法,但是只有继承该接口才可以被远程调用
1 2 3 4 5 6 7 8 9
| package rmi;
import java.io.IOException; import java.rmi.Remote;
public interface Rmi extends Remote { public String hello() throws IOException; }
|
RemoteException
RemoteException是所有在远程调用中所抛出异常的超类,所有能够被远程调用的方法声明,都需要抛出此异常
Naming
提供向注册中心保存远程对象引用或者从注册中心获取远程对象引用的方法。这个类中的方法都是静态方法,每一个方法都包含了一个类型为String的name参数, 这个参数是URL格式,形如://host:port/name
1 2 3 4 5 6 7 8 9
| import java.rmi.Naming;
public class ClientDemo { public static void main(String[] args) throws Exception{ Naming.lookup("rmi://127.0.0.1:1099/rmi"); String hello = rmi.hello(); System.out.println(hello); } }
|
Registry
一个interface, 其功能和Naming
类似,每个方法都有一个String类型的name参数,但是这个name不是URL格式,是远程对象的一个命名。Registry的实例可以通过方法LocateRegistry.getRegistry()
获得
1 2 3 4 5 6 7 8 9 10
| import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry;
public class ClientDemo { public static void main(String[] args) throws Exception{ Registry registry = LocateRegistry.getRegistry("127.0.0.1",1099); Rmi rmi1 = (Rmi) registry.lookup("rmi"); System.out.println(rmi1.hello()); } }
|
LocateRegistry
用于获取到注册中心的一个连接,这个连接可以用于获取一个远程对象的引用。也可以创建一个注册中心。
1 2
| Registry registry = LocateRegistry.createRegistry(1099); Registry registry = LocateRegistry.getRegistry("127.0.0.1",1099);
|
RemoteObject
重新覆写了Object
对象中的equals,hashCode,toString方法,从而可以用于远程调用
UnicastRemoteObject
用于RMI Server中导出一个远程对象并获得一个stub。这个stub封装了底层细节,用于和远程对象进行通信。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import java.io.IOException; import java.io.InputStream; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject;
public class RemoteHelloworld extends UnicastRemoteObject implements Rmi{ @Override public String hello() throws IOException { Runtime runtime = Runtime.getRuntime(); InputStream in = runtime.exec("id").getInputStream(); byte[] bytes = new byte[1024]; in.read(bytes); return new String(bytes); } protected RemoteHelloworld() throws RemoteException { super(); }
}
|
Unreferenced
一个interface, 声明了方法:void unreferenced()
如果一个远程对象实现了此接口,则这个远程对象在没有任何客户端引用的时候,这个方法会被调用。
服务端
服务端为kali
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| rmi ├── RemoteHelloworld.java ├── Rmi.java └── Servet.java
package rmi;
import java.io.IOException; import java.io.InputStream; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject;
public class RemoteHelloworld extends UnicastRemoteObject implements Rmi{ public String hello() throws IOException { Runtime runtime = Runtime.getRuntime(); InputStream in = runtime.exec("id").getInputStream(); byte[] bytes = new byte[1024]; in.read(bytes); return new String(bytes); } protected RemoteHelloworld() throws RemoteException { super(); } }
package rmi;
import java.io.IOException; import java.rmi.Remote;
public interface Rmi extends Remote { public String hello() throws IOException; }
package rmi;
import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry;
public class Servet { public static void main(String[] args) throws Exception { Rmi rmi = new rmi.RemoteHelloworld(); Registry registry = LocateRegistry.createRegistry(1099); System.out.println("rmi server already start"); registry.rebind("rmi",rmi); } }
|
客户端
客户端为Mac
客户端目录结构应该与服务端保持一致,并且客户端与服务端都应该有相同的Remote接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| rmi ├── ClientDemo.java └── Rmi.java
package rmi;
import java.rmi.Naming; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry;
public class ClientDemo { public static void main(String[] args) throws Exception{
Registry registry = LocateRegistry.getRegistry("172.16.173.2",1099); Rmi rmi1 = (Rmi) registry.lookup("rmi"); System.out.println(rmi1.hello()); } }
package rmi;
import java.rmi.Remote;
public interface Rmi extends Remote { public String hello() throws Exception; }
|
最终成功利用