更新时间:2023-10-17 21:15:22
在JDK之前v5必须使用 rmic
( RMI编译器)生成RMI存根。这是从JDK v5自动完成的。此外,您还可以从Java代码中启动RMI注册表。要从简单的RMI应用程序开始,您可能需要按照以下步骤操作:
Prior to JDK v5 one had to generate the RMI stubc using the rmic
(RMI Compiler). This is done automatically from JDK v5 on. Moreover, you can start the RMI Registry from within the Java code as well. To start with a simple RMI application you may want to follow the following steps:
import java.rmi.*;
public interface SomeInterface extends Remote {
public String someMethod1() throws RemoteException;
public int someMethod2(float someParameter) throws RemoteException;
public SomeStruct someStructTest(SomeStruct someStruct) throws RemoteException;
}
import java.rmi.*;
import java.rmi.server.*;
public class SomeImpl extends UnicastRemoteObject implements SomeInterface {
public SomeImpl() throws RemoteException {
super();
}
public String someMethod1() throws RemoteException {
return "Hello World!";
}
public int someMethod2( float f ) throws RemoteException {
return (int)f + 1;
}
public SomeStruct someStructTest(SomeStruct someStruct) throws RemoteException {
int i = someStruct.getInt();
float f = someStruct.getFloat();
someStruct.setInt(i + 1);
someStruct.setFloat(f + 1.0F);
return someStruct;
}
}
import java.io.*;
public class SomeStruct implements Serializable {
private int i = 0;
private float f = 0.0F;
public SomeStruct(int i, float f) {
this.i = i;
this.f = f;
}
public int getInt() {
return i;
}
public float getFloat() {
return f;
}
public void setInt(int i) {
this.i = i;
}
public void setFloat(float f) {
this.f = f;
}
}
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.net.*;
import java.io.*;
public class SomeServer {
public static void main(String args[]) {
String portNum = "1234", registryURL;
try{
SomeImpl exportedObj = new SomeImpl();
startRegistry( Integer.parseInt(portNum) );
// register the object under the name "some"
registryURL = "rmi://localhost:" + portNum + "/some";
Naming.rebind(registryURL, exportedObj);
System.out.println("Some Server ready.");
} catch (Exception re) {
System.out.println("Exception in SomeServer.main: " + re);
}
}
// This method starts a RMI registry on the local host, if it
// does not already exist at the specified port number.
private static void startRegistry(int rmiPortNum) throws RemoteException{
try {
Registry registry = LocateRegistry.getRegistry(rmiPortNum);
registry.list( );
// The above call will throw an exception
// if the registry does not already exist
} catch (RemoteException ex) {
// No valid registry at that port.
System.out.println("RMI registry is not located at port " + rmiPortNum);
Registry registry = LocateRegistry.createRegistry(rmiPortNum);
System.out.println("RMI registry created at port " + rmiPortNum);
}
}
}
import java.io.*;
import java.rmi.*;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
public class SomeClient {
public static void main(String args[]) {
try {
String hostName;
String portNum = "1234";
String registryURL = "rmi://localhost:" + portNum + "/some";
SomeInterface h = (SomeInterface)Naming.lookup(registryURL);
// invoke the remote method(s)
String message = h.someMethod1();
System.out.println(message);
int i = h.someMethod2(12344);
System.out.println(i);
SomeStruct someStructOut = new SomeStruct(10, 100.0F);
SomeStruct someStructIn = new SomeStruct(0, 0.0F);
someStructIn = h.someStructTest(someStructOut);
System.out.println( someStructIn.getInt() );
System.out.println( someStructIn.getFloat() );
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
较大的客户端 - 服务器应用程序应分为三个模块: client
, server
和 common
(对于服务器和客户端代码之间共享的类,即本例中的远程接口和非基本对象)。然后,客户端应用程序将从类路径上的客户端
+ 公共
模块和 server
+ common
模块。
A larger client-server application should be divided into three modules:client
, server
, and common
(for classes shared between the server and client code, i.e. the remote interface and the non-primitive object in this example). The client application will then be created from client
+ common
modules on the classpath and the server from server
+ common
modules on the classpath.
我用这个例子很多年了以前学习RMI的基础知识,它仍然有效。然而,它远非完美(使用默认的Java包,不正确的异常处理,主机名和端口参数是硬编码的,不可配置等)。
I used this example many years ago to learn basics of RMI and it still works. However it is far from being perfect (default Java package used, incorrect exception handling, hostname and port parameters are hard-coded and not configurable, etc.)
然而,它对初学者有好处。所有文件都可以放在一个目录中,并使用简单的 javac * .java
命令进行编译。然后可以使用 java SomeServer
启动服务器应用程序,通过启动 java SomeClient
命令启动客户端。
Nevertheless, it is good for starters. All the files can be placed in one directory and compiled using the simple javac *.java
command. The server application can then be started using the java SomeServer
and the client one by launching the java SomeClient
command.
我希望这有助于理解Java RMI,事实上,它远比这复杂得多。
I hope this helps to understand the Java RMI which is, in fact, far more complicated than just this.