我有一个启动第二个JVM的项目。目前我正在使用RMI在两者之间进行通信。在我自己的机器上运行良好。只有本地主机的RMI?
我需要能够部署在Windows 7机器这个项目,我没有权限修改防火墙规则。
注册表(从第一JVM中推出了高任意端口上)被阻止从在这些机器上打开一个服务器套接字。
有没有办法来限制RMI只能听本地连接;这样Windows防火墙会很酷吗?
另外,有将需要很少的功能变化的良好替代IPC的方法?
干杯。
我有一个启动第二个JVM的项目。目前我正在使用RMI在两者之间进行通信。在我自己的机器上运行良好。只有本地主机的RMI?
我需要能够部署在Windows 7机器这个项目,我没有权限修改防火墙规则。
注册表(从第一JVM中推出了高任意端口上)被阻止从在这些机器上打开一个服务器套接字。
有没有办法来限制RMI只能听本地连接;这样Windows防火墙会很酷吗?
另外,有将需要很少的功能变化的良好替代IPC的方法?
干杯。
这比第一次看起来更复杂。需要的是限制注册表正在监听的IP 地址,但不限制端口。问题是RMI注册实现程序(rmiregistry
)实际上并没有提供任何机制来限制它监听的IP地址;它总是监听每个可用的网络接口。只有两种实际的限制机制:
localhost
,127.0.0.1
)RMI注册的一个特殊版本,因为Windows 不抱怨只能从本地机器达到插座。这第二个选项是什么我就勾勒出。这实际上很简单,因为您可以将大部分复杂性委托给现有的类。
import java.io.IOException;
import java.net.*;
import java.rmi.server.*;
import java.rmi.registry.LocateRegistry;
public class RestrictedRMIRegistry implements RMIServerSocketFactory {
public static void main(String... args) throws IOException {
int port = (args.length == 0 ? 1099 : Integer.parseInt(args[0], 10));
RMIClientSocketFactory csf = RMISocketFactory.getDefaultSocketFactory();
RMIServerSocketFactory ssf = new RestrictedRMIRegistry();
LocateRegistry.createRegistry(port, csf, ssf);
}
public ServerSocket createServerSocket(int port) throws IOException {
// Tricky bit; make a server socket with bound address
return new ServerSocket(port, 0, InetAddress.getLocalHost());
}
}
这和正常rmiregistry
实现之间唯一的区别是,它使用了都客户端和服务器套接字工厂的默认值。
正是我在找的 – FlightOfStairs 2012-02-22 14:38:12
我发现这对于一个类似的问题非常有帮助,我为了安全目的想限制RMI到本地主机,但是我发现我还需要限制端口1098套接字。做完b y将这个相同的套接字工厂提供给远程类的构造器,例如 公共类RemoteStatistics扩展了UnicastRemoteObject { 私人RemoteStatistics()将抛出RemoteException { 超(1098, 空, RestrictableRMIRegistry.getInstance()); } – Fanjita 2014-04-29 11:16:48
对不起,我是一个有SO注释标记的noob,我努力让这些代码格式正确。 – Fanjita 2014-04-29 11:23:16
好的替代方法称为HTTP上的Web服务,通常用于出站连接。
问题在于入站连接。我认为,“正确的”架构是当部署在防火墙后面的进程通过第三进程互相通信时 - 即安装在入站HTTP连接不受限制的地方的服务器。因此,防火墙后面的2个组件仅执行到服务器的出站HTTP连接。
我不需要这样做。系统的所有部分都在一台机器上运行,并且不需要外部资源。问题是Windows防火墙阻止了rmiregistry,这是我用于本地IPC的。 – FlightOfStairs 2012-02-16 09:48:34
尝试打开注册表(或涉及您的方案中的任何其他Java进程),当java.rmi.server.hostname
属性设置为127.0.0.1
。
这不是一个坏主意,但它不会影响注册表,只会从其中设置属性的JVM导出其他远程存根,因为注册表存根本地构建,而不是远程获取。限制SocketPermission“接受”的.policy文件是另一种可能性。 – EJP 2012-02-22 09:26:20
嗯,你说得对。当我使用该集合运行'rmiregistry'时,它仍然打开一个敞开的端口。 :-(我知道如何解决,但是需要一点点写,因为它需要代码 – 2012-02-22 09:47:47
'java.rmi.server.hostname'不控制监听端口,它控制写入存根。'LocateRegistry.getRegistry()'从你提供的host:port本地构造一个Registry stub,所以在注册表的JVM上对java.rmi.server.hostname的设置不会对该stub产生任何影响。获取注册表或任何其他远程对象来打开绑定到127.0.0.1的端口时,必须指定一个在导出时会这样做的'RMIServerSocketFactory'。 – EJP 2012-02-22 09:57:33
这就是Web服务(在8080端口上工作)获得普及的原因。 – 2012-02-16 08:28:51
我不知道这将如何帮助?我可以在两者之间打开一个本地http连接,但是在那个阶段,我最好只是在套接字上运行一个对象流呢? – FlightOfStairs 2012-02-16 10:00:02