我有一個啓動第二個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