2011-12-13 175 views
7

我工作的一個RMI命令行的比賽,但是,每當我嘗試我的服務,我收到這樣的錯誤:Java RMI的連接異常:拒絕連接主機/超時

java.rmi.ConnectException: Connection refused to host: 192.168.56.1; nested exception is: 
    java.net.ConnectException: Connection timed out: connect 

這是我Server主類:

public class RMIWar { 

    public static void main(String[] args) throws RemoteException, MalformedURLException { 
     try { 
      Controle obj = new Controle(4); 
      Registry reg = LocateRegistry.createRegistry(1099); 
      System.out.println("Server is ready"); 
      reg.rebind("CtrlServ", obj); 
     } 
     catch (Exception e) { 
      System.out.println("Error: " + e.toString()); 
     } 
    } 
} 

主要爲我Client類:

public class RMIWarClient { 
    public static void main(String[] args) throws RemoteException, MalformedURLException, NotBoundException { 
     try { 
      Registry registry = LocateRegistry.getRegistry("localhost"); 
      ControleInt ctrl = (ControleInt) registry.lookup("CtrlServ"); 
      System.out.println("CtrlServ found...\n"); 
      BioRMI bio = new BioRMI(null, 5,5,5); 
      ctrl.thRegister("Test", bio.atk, bio.def, bio.agi); 

     } 

     catch (Exception e) { 
      System.out.println("Error: " + e); 
     } 
    } 
} 

有何建議?

回答

10

測試您的1099端口是否可用。另外,你沒有提到你使用的是什麼操作系統,以及如果你在執行服務器之前啓動了註冊表。

這RMI tutorial解釋:

開始計算引擎之前,您需要啓動RMI 註冊表。 RMI註冊表是一個簡單的服務器端引導程序命名 工具,它使遠程客戶端可以獲得對初始遠程對象的引用。

默認情況下,註冊表在端口1099上運行,與您的端口類似。 作爲教程報告,只是打開命令提示(在Windows)或殼終端(在UNIX-像OS)和類型:

對於Windows(使用javaw進程如果開始不可用):

start rmiregistry 

Solaris OS或Linux

rmiregistry & 

UPDATE

我注意到,遵循Oracle的教程和我之前的項目,在Server類中,您沒有將該對象導出到RMI運行時。 那麼你應該編輯這些行:

Controle obj = new Controle(4); 
Registry reg = LocateRegistry.createRegistry(1099); 
System.out.println("Server is ready"); 
reg.rebind("CtrlServ", obj); 

到:

Controle obj = new Controle(4); 
Controle stub = (Controle) UnicastRemoteObject.exportObject(obj, 0); 
Registry reg = LocateRegistry.createRegistry(1099); 
System.out.println("Server is ready"); 
reg.rebind("CtrlServ", stub); 

因爲教程報道:

靜態UnicastRemoteObject.exportObject中方法導出 提供遠程對象,以便它可以從遠程客戶端接收遠程方法的調用 。

此外,如果您使用的是同一臺主機的RMI調用,它不需要在Client類:

Registry registry = LocateRegistry.getRegistry("localhost"); 

簡單地調用:

Registry registry = LocateRegistry.getRegistry(); 

因爲Oracle報告:

LocateRegistry.getReg的無參數重載伊士萊合成一個 參照本地主機和默認的註冊表 端口上的註冊表,1099必須使用比是否之外的端口上創建 註冊表中有一個int參數的重載1099

+0

這些都不會導致連接超時。 – EJP

+2

防火牆端口 –

+0

@EJP關於連接超時,我寫道:「測試你的1099端口是否可用」。這將意味着檢查端口是否可用或防火牆。我關於啓動rmiregistry的說明是因爲OP沒有寫任何有關這方面的內容,並且因爲有時服務的不執行是拒絕連接的原因。如果客戶想要執行服務器的方法,但如果服務器沒有在服務本地運行,則客戶端將永遠不會執行該方法。 –

0

要小心端口因爲他們可能被阻止的防火牆,例如,如果您正在工作或大學的安全區域工作,管理員可能已經實施了一些保護...

0

我不看你怎麼可能從那個代碼中獲得這個異常。根據您的服務器和客戶端在同一主機上運行的代碼,並且您不會在同一主機中獲得連接超時。

因此,假如這不是你真正的代碼,你正在尋找了正確的註冊表(主機參數getRegistry()),我會問192.168.56.1是否是你希望看到給您的網絡拓撲的IP地址。這是一個內部局域網地址,如果你的客戶端在局域網之外,它應該試圖連接到一個更公共的IP地址。如果地址不是你所期望的,我可以參考item A.1 on the RMI FAQ