2016-07-30 24 views
1

Ich habe rmi Server und ich habe mehrere Netzwerkadapter auf meinem Computer.RMI: funktioniert rmi Server zur gleichen Zeit kann nur mit einer Netzwerkschnittstelle arbeiten

Um java.rmi.ConnectException: Connection refused to host: 127.0.1.1; nicht erhält ich die java.rmi.server.hostname Eigenschaft auf meinem RMI-Server gesetzt (siehe https://stackoverflow.com/a/15696021/5057736)

es bedeutet, dass nur in einer Instanz von JVM kann der RMI-Server zur gleichen Zeit arbeitet mit einer Netzwerkschnittstelle ohne Betriebssystemeinstellungen?

+0

Ich denke, Ports mehr das Problem ist als die Netzwerk-Schnittstelle –

+0

@ cricket_007 Ich verstehe dich nicht - ich habe keine Probleme mit Ports mit rmi arbeiten. Das Problem liegt in der Verwendung unterschiedlicher Netzwerkschnittstellen. –

+0

Vielleicht habe ich dann falsch verstanden. Sind beide Netzwerkschnittstellen auf den gleichen Hostnamen und ähnliches verteilt? –

Antwort

0

Nach dem Lesen https://community.oracle.com/blogs/emcmanus/2006/12/22/multihomed-computers-and-rmi und diesem https://community.oracle.com/thread/1178328?start=0 habe ich die folgende Lösung - in allen Anwendung Export RMIRemoteObjects wir an einem Ort. Mit dieser Lösung kann RMI in einer JVM-Instanz gleichzeitig mit verschiedenen Netzwerkschnittstellen arbeiten. RmiRemoteManager wird für jede Socket-Adresse (Netzwerkschnittstelle + Port) erstellt. Vor dem Export müssen wir java.rmi.server.hostname definieren. Diese Lösung funktioniert. Bitte denken Sie daran, dass dies eine Problemumgehung für die RMI-Beschränkung ist.

class ClientSocketFactory implements RMIClientSocketFactory,Serializable{ 

    private InetAddress address; 

    public ClientSocketFactory(InetAddress address) 
    { 
     this.address = address; 
    } 

    @Override 
    public Socket createSocket(String host, int port) throws IOException { 
     Socket socket =new Socket(address, port); 
     return socket; 
    } 

    @Override 
    public boolean equals(Object that) 
    { 
     return that != null && this.getClass() == that.getClass(); 
    } 
} 

class ServerSocketFactory implements RMIServerSocketFactory{ 

    private InetAddress address; 

    public ServerSocketFactory(InetAddress address) 
    { 
     this.address = address; 
    } 

    @Override 
    public ServerSocket createServerSocket(int port) throws IOException{ 
     return new ServerSocket(port, 0, address); 
    } 

    @Override 
    public boolean equals(Object that) 
    { 
     return that != null && this.getClass() == that.getClass(); 
    } 
} 

public class RmiRemoteManager { 

    private Registry registry; 

    private InetSocketAddress socketAddress; 

    private ServerSocketFactory serverSocketFactory; 

    private ClientSocketFactory clientSocketFactory; 

    public RmiRemoteManager(InetSocketAddress socketAddress) { 
     try { 
      this.socketAddress = socketAddress; 
      serverSocketFactory=new ServerSocketFactory(InetAddress.getByName(socketAddress.getHostName())); 
      clientSocketFactory=new ClientSocketFactory(InetAddress.getByName(socketAddress.getHostName())); 
      //the registry is exported via createRegistry. 
      registry = LocateRegistry.createRegistry(this.socketAddress.getPort(),clientSocketFactory,serverSocketFactory); 
     } catch (UnknownHostException ex) { 
      Logger.getLogger(RmiRemoteManager.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (RemoteException ex) { 
      Logger.getLogger(RmiRemoteManager.class.getName()).log(Level.SEVERE, null, ex); 
     } 

    } 

    private synchronized static Remote export(Remote remoteObject,InetSocketAddress sa,ClientSocketFactory csf,ServerSocketFactory ssf){ 
     try { 
      System.setProperty("java.rmi.server.hostname",sa.getHostName()); 
      return UnicastRemoteObject.exportObject(remoteObject,sa.getPort(),csf,ssf); 
     } catch (RemoteException ex) { 
      Logger.getLogger(RmiRemoteManager.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     return null; 
    } 

    public void export(Remote remoteObject,String url){ 
     try { 
      Remote stub=export(remoteObject,socketAddress,clientSocketFactory,serverSocketFactory); 
      remoteObjects.add(remoteObject); 
      if (url!=null){ 
       urlsByRemoteObjects.put(remoteObject, url); 
       registry.rebind(url, stub); 
      } 
     } catch (RemoteException ex) { 
      Logger.getLogger(RmiRemoteManager.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 
1

Einstellung java.rmi.server.hostname betrifft nur, was in den Stub geschrieben wird. Es hat keine Auswirkungen auf das Zuhören. RMI hört immer auf 0.0.0.0, außer Sie verwenden eine RMIServerSocketFactory, die nicht.

+0

@ JimJim2000 Wenn Sie viel mehr von diesen Fragen haben, kann ich vorschlagen, dass Sie mein Buch * java.rmi: der Wegweiser für Remote Method Invocation, erhalten * Pitt & McNiff, Addison Wesley 2001. Nicht mehr in drucke aber viele s/h Kopien um. Alles, was du bisher gefragt hast, ist darin enthalten. – EJP

+0

Vielen Dank für Ihre Vorschläge, ich werde einen Blick darauf werfen. Was ist mit deiner Antwort? Nehmen wir an, wir haben eine Instanz von JVM und es gibt zwei RmiServer 192.168.1.0:2525 und 192.168.1.1:3636 darauf. Dann funktionieren Stubs nur für einen Server, denn wie ich aus Ihrer Antwort in ALLEN Stubs verstehe, wird der gleiche 'java.rmi.server.hostname' geschrieben? –

+0

Das ist richtig. – EJP