eberndbrot
Grünschnabel
Hallo,
ich brauche für ein Projekt eine RMI-Client-Server-Architektur und bin inzwischen am Verzweifeln. Diverse Beispiele habe ich ausprobiert und bei allen ist es in der Regel das Gleiche:
In meinem Heimnetz zwischen zwei Rechnern (192.168...) geht es wunderbar. Aber sobald ich es übers große Internet oder sogar zwischen zwei Rechnern im Büro teste, ist es damit vorbei.
Der Code in der Testvariante sieht zusammengefasst so aus:
Serverinterface:
Server:
Der Server selbst wird von einer Util-Klasse mit folgender Methode initialisiert:
Der Client sieht folgendermaßen aus:
Starte ich nun den Server über die Util-Klasse mit initiateServer("pacoservice",3434) und den Client auf einem anderen Rechner mit client.connect("pacoservice", "12.34.56.78", 3434), läuft alles wie geschmiert und der Client gibt aus:
und beendet mit TRUE (Anm.: 12.34.56.78 ist meine aktuelle Heim-IP, die Ports 3434 und 3435 werden auf den Serverrechner geforwardet)
Tja, versuche ich es mit dem Client von einem Bürorechner nach Hause, ist nach "Client found services: pacoservice" erstmal 3 Minuten Warten angesagt, bis er den Lookup schafft und nach 2 weiteren Minuten mit einer TimeOut-Exception abbricht.
Wenn ich von einem Bürorechner zum anderen verbinden will, kommt gar dies:
11.11.11.11 ist in dem Fall mal die IP des Serverrechners.
Sobald ich also versuche, eine Methode vom bereits gefundenen Server entfernt aufzurufen, geht es in die Hose. Außer, alles läuft daheim.
Ich habe inzwischen keine Ideen mehr, was ich noch versuchen könnte. An den Firewalls sollte es eigentlich nicht liegen. Ich habe den Verdacht, dass es am UnicastRemoteObject liegen könnte. Denn wenn ich stattdessen nämlich beim Initialisieren
srv = new Server();
registry.rebind(sname, srv);
benutze und dann zwangsläufig das Serverinterface serializable mache, klappt überall alles. Nur nützen mir serialisierte Serverobjekte reichlich wenig.
Falls irgendwer ne Weltidee hat, wäre ich wirklich dankbar. Achja, braucht man wirklich zwei Ports? Bei der serialisierten Severvariante schein ich ja nur mit 3434 auszukommen.
Gruß, eberndbrot
Total entnervt. Erstmal Mittag...
ich brauche für ein Projekt eine RMI-Client-Server-Architektur und bin inzwischen am Verzweifeln. Diverse Beispiele habe ich ausprobiert und bei allen ist es in der Regel das Gleiche:
In meinem Heimnetz zwischen zwei Rechnern (192.168...) geht es wunderbar. Aber sobald ich es übers große Internet oder sogar zwischen zwei Rechnern im Büro teste, ist es damit vorbei.
Der Code in der Testvariante sieht zusammengefasst so aus:
Serverinterface:
Code:
package paco.comm;
public interface IServer extends java.rmi.Remote {
public void justCheck() throws java.rmi.RemoteException;
}
Server:
Code:
package paco.comm;
import java.rmi.RemoteException;
public class Server implements IServer {
private int c;
public Server() throws RemoteException{
System.out.println(paco.Util.getTimestamp()+" Serverobj: initiated");
c = 0;
}
public void justCheck() {
System.out.print("Checked:");
c++;
System.out.println(" No."+c);
}
}
Der Server selbst wird von einer Util-Klasse mit folgender Methode initialisiert:
Code:
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
...
public static Server initiateServer(String sname, int port)
{
Server srv;
try {
Registry registry = LocateRegistry.createRegistry(port);
srv = new Server();
IServer stub = (IServer) UnicastRemoteObject.exportObject(srv, 3435);
registry.rebind(sname, stub);
System.out.println(getTimestamp()+" comm.Util: Service "+sname+" bound in registry");
return srv;
} catch (Exception e) {
System.out.println("comm.Util: Server exception: " + e.getMessage());
e.printStackTrace();
return null;
}
Der Client sieht folgendermaßen aus:
Code:
package paco.comm;
import java.rmi.registry.*;
import paco.comm.IServer;
public class Client {
private String name;
private IServer myserver;
public Client(String name){
this.name = name;
}
public String getName(){
return name;
}
public boolean connect(String name, String host, int port) {
try {
System.out.println(paco.Util.getTimestamp()+" Client: connecting...");
Registry registry = LocateRegistry.getRegistry(host,port);
System.out.println(paco.Util.getTimestamp()+" Client located registry: "+registry);
String l[] = registry.list();
System.out.print(paco.Util.getTimestamp()+" Client found services: ");
for (int i = 0; i < l.length; i++) {
System.out.print(l[i]+" ");
}
System.out.println();
myserver = (IServer) registry.lookup(name);
System.out.println(paco.Util.getTimestamp()+" Client found server: "+myserver);
myserver.justCheck();
return true;
} catch (Exception e) {
System.out.println(paco.Util.getTimestamp()+" Client exception: "+e.getMessage());
e.printStackTrace();
return false;
}
}
}
Starte ich nun den Server über die Util-Klasse mit initiateServer("pacoservice",3434) und den Client auf einem anderen Rechner mit client.connect("pacoservice", "12.34.56.78", 3434), läuft alles wie geschmiert und der Client gibt aus:
Code:
23.07.2008 10:42:27 CEST Client: connecting...
23.07.2008 10:42:27 CEST Client located registry: RegistryImpl_Stub[UnicastRef [liveRef: [endpoint:[12.34.56.78:3434](remote),objID:[0:0:0, 0]]]]
23.07.2008 10:42:27 CEST Client found services: pacoservice
23.07.2008 10:42:27 CEST Client found server: Proxy[IServer,RemoteObjectInvocationHandler[UnicastRef [liveRef: [endpoint:[192.168.0.3:3435](remote),objID:[2834f9a4:11b4f1554fb:-7fff, -8658223623149844210]]]]]
Tja, versuche ich es mit dem Client von einem Bürorechner nach Hause, ist nach "Client found services: pacoservice" erstmal 3 Minuten Warten angesagt, bis er den Lookup schafft und nach 2 weiteren Minuten mit einer TimeOut-Exception abbricht.
Wenn ich von einem Bürorechner zum anderen verbinden will, kommt gar dies:
Code:
23-Jul-2008 11:10:00 CEST Client: connecting...
23-Jul-2008 11:10:00 CEST Client located registry: RegistryImpl_Stub[UnicastRef[liveRef: [endpoint:[11.11.11.11:3434](remote),objID:[0:0:0, 0]]]]
23-Jul-2008 11:10:00 CEST Client found services: pacoservice
23-Jul-2008 11:10:00 CEST Client found server: Proxy[IServer,RemoteObjectInvocationHandler[UnicastRef [liveRef: [endpoint:[127.0.0.2:3435](remote),objID:[3145e036:11b4f2c910f:-7fff, -4761376038667053011]]]]]
23-Jul-2008 11:10:00 CEST Client exception: Connection refused to host: 127.0.0.2; nested exception is:
java.net.ConnectException: Connection refused java.rmi.ConnectException: Connection refused to host: 127.0.0.2; nested exception is:
java.net.ConnectException: Connection refused
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:601)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:198)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:184)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:110)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:178)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:132)
at $Proxy0.justCheck(Unknown Source)
at paco.comm.Client.connect(Client.java:50)
at StartClient.main(StartClient.java:13)
Caused by: java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:519)
at java.net.Socket.connect(Socket.java:469)
at java.net.Socket.<init>(Socket.java:366)
at java.net.Socket.<init>(Socket.java:180)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:128)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:595)
... 8 more
Sobald ich also versuche, eine Methode vom bereits gefundenen Server entfernt aufzurufen, geht es in die Hose. Außer, alles läuft daheim.
Ich habe inzwischen keine Ideen mehr, was ich noch versuchen könnte. An den Firewalls sollte es eigentlich nicht liegen. Ich habe den Verdacht, dass es am UnicastRemoteObject liegen könnte. Denn wenn ich stattdessen nämlich beim Initialisieren
srv = new Server();
registry.rebind(sname, srv);
Falls irgendwer ne Weltidee hat, wäre ich wirklich dankbar. Achja, braucht man wirklich zwei Ports? Bei der serialisierten Severvariante schein ich ja nur mit 3434 auszukommen.
Gruß, eberndbrot
Total entnervt. Erstmal Mittag...