我對Java RMI沒有太多經驗。我正在嘗試實施簡單的RMI通信,但遇到了問題。Java RMI客戶端和遠程服務器連接拒絕本地主機
這裏我RMI客戶
public class MainClientApplication {
public static final String FILE_NAME_RMI_POLICY = "rmi.policy";
public static final String RMI_DOMAIN = "mydomain.net";
public static final String RMI_ENDPOINT = "/MD5Decrypter";
public static final String PROTOCOL = "rmi://";
public static void main(String[] args) {
System.out.println(System.getProperty("user.dir") + File.separator + FILE_NAME_RMI_POLICY);
System.setProperty("java.security.policy", System.getProperty("user.dir") + File.separator + FILE_NAME_RMI_POLICY);
String remoteHost = String.format("%s%s%s", PROTOCOL, RMI_DOMAIN, RMI_ENDPOINT);
System.setSecurityManager(new SecurityManager());
try {
ComputeEngine computeEngine = (ComputeEngine) Naming.lookup(remoteHost);
SwingUtilities.invokeLater(() -> new MainWindow("MD5 Decryption", computeEngine));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
通信inerface
public interface ComputeEngine extends Remote {
Object executeTask(Task t) throws RemoteException;
}
我的服務器
public class MainServer {
public static final int PORT = 1099;
public static final String RMI_ENDPOINT = "MD5Decrypter";
public static final String FILE_NAME_RMI_POLICY = "rmi.policy";
public static final String RMI_DOMAIN = "mydomain.net";
public static final String PROTOCOL = "rmi://";
public MainServer() {
try {
System.setProperty("java.security.policy", System.getProperty("user.dir") + File.separator + FILE_NAME_RMI_POLICY);
//System.setProperty("java.rmi.server.hostname", RMI_IP);
System.setProperty("java.rmi.server.hostname", RMI_DOMAIN);
System.setSecurityManager(new SecurityManager());
ComputeEngine computeEngine = new ComputeEngineExecutor();
// Naming.rebind(String.format("%s%s:%d/%s", PROTOCOL, RMI_DOMAIN, PORT, RMI_ENDPOINT), computeEngine);
Naming.rebind(RMI_ENDPOINT, computeEngine);
System.out.println("Successfully started RMI Server");
} catch (RemoteException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
MainServer mainServer = new MainServer();
}
}
而且rmi.policy
grant {
permission java.net.SocketPermission "*:1024-65535", "connect, accept";
permission java.io.FilePermission "-", "read";
permission java.net.SocketPermission "*:80", "connect";
};
所以我在我的服務器rmiregistry 1099
上啓動了rmiregistry。一切都很好,直到調用遠程對象方法。
這裏有
讓我們考慮,我的域名是mydomain.net
,我使用靜態IP承載它在我的服務器在家裏我的腳步。在服務器上
- 運行
rmiregistry
服務器上
- 運行服務器應用程序在任何PC上
- 運行客戶端應用程序
- 點擊按鈕來調用遠程方法
如此看來,一切所連接併成功綁定,因爲如果強制輸入無效域,端點或拒絕rmiregistry未啓動 - 引發java.rmi.ConnectException
。
但是,當我嘗試調用遠程對象上的任何方法,BTW這已被檢索到的成功,它拋出一個java.rmi.ConnectException
java.rmi.ConnectException: Connection refused to host: 127.0.1.1; nested exception is:
java.net.ConnectException: Connection refused
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:130)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:227)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:179)
at com.sun.proxy.$Proxy0.executeTask(Unknown Source)
at ui.MainWindow.lambda$initGui$0(MainWindow.java:49)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
,我可以理解,問題是它(服務器)迫使我連接到我的本地主機而不是遠程。
P.S localhost上一切完美(客戶端和服務器上的一臺PC上)
請幫助解決這個問題。
編輯
我忘了告訴大家,我試圖設置的java.rmi.server.hostname
屬性,在這種情況下,它需要大量的時間來啓動服務器,並與異常結束。
請參閱RMI FAQ項目A.1。 – EJP
感謝您的回答,我已經嘗試設置'java.rmi.server.hostname',但它奇怪地工作,它需要大量的時間來啓動服務器和連接,但仍然無法工作 - 超時。 – CROSP
你把它設置成什麼?你必須告訴我們你做了什麼。我們無法看到您的電腦。注意你必須在服務器JVM上設置* * – EJP