Java RMI 客户端和远程服务器拒绝连接到本地主机
Java RMI client and remote server Connection Refused to localhost
我对 Java RMI 不是很熟悉。我正在尝试实现简单的 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();
}
}
}
通讯界面
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 rmiregistry 1099
。在调用远程对象方法之前一切正常。
这是我的步骤
假设我的域名是 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[=15=](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 在本地主机上一切正常(一台 PC 上的客户端和服务器)
请帮忙解决这个问题
编辑
忘记说了,我试过设置属性 of java.rmi.server.hostname
,这样的话启动服务器需要很多时间,异常结束
撇开 127.0.0.1 问题不谈,已由 java.rmi.server.hostname
解决,您现在的问题是连接超时。这将由您的防火墙引起。您需要在特定端口上导出远程对象,并且需要在防火墙中打开该 TCP 端口。
我对 Java RMI 不是很熟悉。我正在尝试实现简单的 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();
}
}
}
通讯界面
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 rmiregistry 1099
。在调用远程对象方法之前一切正常。
这是我的步骤
假设我的域名是 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[=15=](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 在本地主机上一切正常(一台 PC 上的客户端和服务器)
请帮忙解决这个问题
编辑
忘记说了,我试过设置属性 of java.rmi.server.hostname
,这样的话启动服务器需要很多时间,异常结束
撇开 127.0.0.1 问题不谈,已由 java.rmi.server.hostname
解决,您现在的问题是连接超时。这将由您的防火墙引起。您需要在特定端口上导出远程对象,并且需要在防火墙中打开该 TCP 端口。