问题
I am newbie. I cannot understand RMI
correctly. There are tons of tutorials available on the internet ,but all of them are for the local host as I can understand. Both server and client run on the same machine.
I want to run client on any machine and the host will be on the one computer lets consider IP - 11.11.11.11
. On the 1099
.
But how can I achieve this, where should I specify my IP on the client side. As I understand naming convertion is used, like DNS but anyway when I need to connect to some machine remotely I need to know at least IP address (+mask) and port.
I guess I missed something really important.
Please give some example how to configure RMI remotly not on the same host.
回答1:
First you have to setup a server whose method or object can be accessed by any remote client Below is example code for the server.
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface MyCalc extends Remote{
int add(int a, int b) throws RemoteException;
}
import java.rmi.RemoteException;
public class MyCalcImpl implements MyCalc {
@Override
public int add(int a, int b) throws RemoteException {
return (a + b);
}
}
Start the rmi registry on server machine so you can register your object to this registry and better you run it where you have placed your classes otherwise you will get ClassNotFound.
rmiregistry 1099
Note: you might need to change the port if port is already in use.
Register you object to rmi registry with name 'calculator'.
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class MyRMIServer {
public static void main(String[] args) throws Exception {
System.setProperty("java.security.policy","file:///tmp/test.policy");
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
try {
String name = "Calculator";
MyCalc engine = new MyCalcImpl();
MyCalc stub = (MyCalc) UnicastRemoteObject.exportObject(engine, 0);
Registry registry = LocateRegistry.getRegistry(1099);
System.out.println("Registering Calculator Object");
registry.rebind(name, stub);
} catch (Exception e) {
System.err.println("Exception:" + e);
e.printStackTrace();
}
}
}
Note: To run the program you have to setup a security policy file and for that creat a file e.g. test.policy and copy below content.
grant {
permission java.security.AllPermission;
permission java.net.SocketPermission "localhost:1099", "connect, resolve";
permission java.net.SocketPermission "127.0.0.1:1099", "connect, resolve";
permission java.net.SocketPermission "localhost:80", "connect, resolve";
};
You can change IP and port as per your case.
After starting the server, suppose your server's IP address is 11.11.11.11 then you can invoke the MyCalc's add() on the server. So on your client machine your client code would be like:
Copy the MyCalc class from server to client machine so you can set it to the classpath while compiling client's code.
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class MyRMIClient {
public static void main(String args[]) {
System.setProperty("java.security.policy","file:///tmp/test.policy");
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
try {
String name = "Calculator";
String serverIP = "11.11.11.11"; // or localhost if client and server on same machine.
int serverPort = 1099;
Registry registry = LocateRegistry.getRegistry(serverIP, serverPort);
MyCalc mycalc = (MyCalc) registry.lookup(name);
int result = mycalc.add(10, 20);
System.out.println("Result:" + result);
} catch (Exception e) {
System.err.println("ComputePi exception:");
e.printStackTrace();
}
}
}
compile and test the client's code.
EDIT: edited to remove dependency on rmi compiler (rmic)
回答2:
You only have to specify the server's IP address in one place: the lookup string supplied to Naming.lookup().
[Unless you have the Linux problem referred to in the RMI FAQ item A.1.]
来源:https://stackoverflow.com/questions/35403765/java-rmi-for-remote-ip-host