2015-02-11 75 views
0

客人的計算機可能位於服務器以外的網絡上。 如果不是,則一切正常,但是當他出現時,會拋出ConnectException在不同的網絡上使用RMI

你知道爲什麼嗎?

額外的信息: 我修改了端口從1099(默認值)到80來試圖解決這個問題,不能正常工作。 使用Wireshark,我看到客人正在使用端口50740.我不明白爲什麼,以前從未看到過這個數字。 我使用.policy文件授予所有權限。

編輯: 我已經服務器IP由.BAT定義。在我的客戶開始時,我也有Locate.createRegistry(80);。客戶使用端口80是否足夠?

奇怪的是,我可以嘗試登錄(我的應用程序要求登錄時啓動),看看我的憑據是否可以。然後,如果客戶端不在同一個網絡上,則引發ConnectException

+0

這不是一個java/rmi的問題imo。 – Andreas 2015-02-11 15:19:56

+0

我認爲這是不可能的,我有這個問題,並在我的情況下,我不得不使用套接字而不是RMI。這裏有一個類似的問題:http://stackoverflow.com/questions/16268391/java-rmi-over-the-internet – fdam 2015-02-11 15:40:07

+0

@Andreas哦,是的。 – EJP 2015-02-11 22:16:05

回答

1

我將端口從1099(默認)修改爲80,試圖解決問題,不起作用。使用Wireshark,我看到客人正在使用端口50740.我不明白爲什麼,以前從未看過這個數字。

當RMI客戶端想要與遠程對象交談時,它通常首先聯繫端口1099上的RMI註冊表以詢問它可以在哪裏找到目標對象。註冊表使用包含目標對象地址(主機名和端口號)的存根響應,客戶端然後可以連接到目標主機和端口以與遠程對象進行通信。

如果在調用UnicastRemoteObject超類構造函數或靜態exportObject方法時未指定顯式端口號,則RMI將選擇一個隨機可用端口號以供使用。這可能是50740的來源 - 它是目標對象正在監聽的端口,而不是註冊表。

但是目標對象地址的第二個元素是主機名 - 如果對象在類似127.0.0.1:50740的地址列在註冊表中,則不同機器上的客戶端將最終嘗試連接到錯誤的對象(位於客戶端的 localhost而不是服務器)。解決方法是確保對象在可以從客戶端解析的正確主機名或IP地址下綁定到註冊表中 - 理論上這應該自動發生,但有時RMI會錯誤地解決它。該解決方案是一個系統屬性傳遞給RMI服務器(該過程是在註冊表中綁定的目標對象)

java -classpath .... -Djava.rmi.server.hostname=192.168.0.1 com.example.MyRmiServer 

替換192.168.0.1與客戶機將用來聊到服務器的正確IP地址。

0

您需要將遠程對象導出到固定的端口號上,然後在防火牆中打開該端口。最簡單的端口是1099,因爲它已經保留了,但它要求你通過LocateRegistry.createRegistry()啓動JVM中的註冊表,而不是使用rmiregistry,所以你可以共享這個端口。