Dickes Rmi Problem beim Methodenaufruf

javaprogger1987

Erfahrenes Mitglied
Also ich habe folgendes Problem und komm da echt nicht weiter.
Ich hab nen Chat mit RMI und Servlets gebastelt (mit Anleitung) und nun klappt das auf meinem PC intern alles wunderbar (Tomcat 5 + Apache). Wenn jetzt allerdings jemand versucht von einem anderen PC(übers Internet) zu verbinden gibt es den Fehler (beim anderen):

Remote exception : Connection refused to host: 192.168.178.20; nested exception is:
java.net.ConnectException: Connection timed out: connect
Fehler beim Abfragen der Userlist:java.rmi.ConnectException: Connection refused to host: 192.168.178.20; nested exception is:
java.net.ConnectException: Connection timed out: connect

Das merkwürdige ist nun, dass die IP 192.168.178.20 meine lokale Netzwerk IP ist. Der Fehler wird auch erst ausgelöst, wenn das Applet versucht eine Methode des Servlets aufzurufen, vorher (Die Abfrage der Servlet-Objekts) klappt alles. Ich hoffe ihr könnt mir helfen, denn ich komm echt nicht weiter.
 
Hast du die policy datei des Servers angepasst? Es gibt eine java.policy in der du die einzelnen Zugriffe über das netz freigeben müsstest. sprich was für zugriffe gestattet sind von wo und von wem.

Ich denke das hat damit zu tun.
Standardmässig ist glaube ich nur der lokale zugriff gestattet.

Du kannst aber auch eine neue java.policy (kann auch anders heissen name ist beliebig, nur musst du dann beim ausführen einen Parameter: -Djava.security.policy=<NamederPolicyDatei> mitgeben) schreiben.

Hier ein kleiner Link:

http://java.sun.com/j2se/1.3/docs/guide/security/PolicyFiles.html

http://www.zerokspot.com/docs/programming.java.rmi.tutorial-ger/

http://java.sun.com/docs/books/tutorial/security1.2/tour1/step3.html

Versuchs mal damit.

Grüsse Torsten


P.S.: Hab vergessen die Java-Seite mitanzugeben, wie ein Policy File aufgebaut werden muss.
 
Zuletzt bearbeitet:
Also ich bins nochmal..
Nach Wochen voll ausprobieren und lesen komm ich immer noch nich weiter...
Also ich benutz ja Tomcat 5.0.28 und starte das ohne Security Manager, dann sollte das doch eigentlich ohne Anpassung der Policydatei gehen. Aber selbst nach dem Anpassen funktioniert es nicht ich bekommen neue Security-Fehler... Hier mal der Code (nur der Server, das Applet sollte in Ordnung sein, weil es sowieso signiert ist und alle Rechte hat) ich weiß nich warum das nich geht...

ChatServer.java
Code:
package chatgame;
 
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.Vector;
 
public interface ChatServer extends Remote {
public void broadcastMessage(String message) throws RemoteException;
public void addClient(ChatClient client, String name, String pass) throws RemoteException;
public void deleteClient(ChatClient client, String name) throws RemoteException;
public Vector getUserList() throws RemoteException;
}

ChatServlet.java:
Code:
package chatgame;
import java.io.*;
import java.net.*;
import java.rmi.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.net.Socket;
import java.util.Vector;
public class ChatServlet
	extends RemoteDaemonServlet
	implements ChatServer {
// rmiClients holds references to all the RMI clients
Vector rmiClients[]= new Vector[2];
 
public void init(ServletConfig config) throws ServletException {
	super.init(config);
	rmiClients[0] = new Vector();
	rmiClients[1] = new Vector();
	init = true;
}
 
public void broadcastMessage(String message) {
	Enumeration enum;
	Enumeration enumN;
	enum = rmiClients[0].elements();
	enumN = rmiClients[1].elements();
	while (enum.hasMoreElements()) {
	 ChatClient chatClient = null;
	 try {
		chatClient = (ChatClient) enum.nextElement();
		chatClient.setNextMessage(message);
		enumN.nextElement();
	 }
	 catch (RemoteException e) {
		deleteClient(chatClient, (String) enumN.nextElement());
	 }
	}
}
 
public void addClient(ChatClient client, String name, String pass) {
	if (checkAccess(name,pass)) {
	 rmiClients[0].addElement(client);
	 rmiClients[1].addElement(name);
	 //Allen mitteilen, dass ein neuer Benutzer da ist
	 updateUserList(client);
	}else {
	 try {
		client.setWrongLogin();
	 }
	 catch (RemoteException ex) {
	 }
	}
}
 
private boolean checkAccess(String name, String pass) {
	//Namens + Password überprüfung hier hin
	return true;
}
 
public void deleteClient(ChatClient client, String name) {
	rmiClients[0].removeElement(client);
	rmiClients[1].remove(name);
	removeUser(name);
}
 
private void updateUserList(ChatClient client) {
	try {
	 String newOne = client.getUserName();
	 for (int i = 0; i < rmiClients[0].size(); i++) {
		if (!rmiClients[0].elementAt(i).equals(client)) {
		 ( (ChatClient) rmiClients[0].elementAt(i)).addUserToList(newOne);
		}
	 }
	}
	catch (RemoteException ex) {
	}
}
 
public Vector getUserList() {
	return rmiClients[1];
}
 
public void removeUser(String name) {
	for (int i = 0; i < rmiClients[0].size(); i++) {
	 try {
		( (ChatClient) rmiClients[0].elementAt(i)).removeUserFromList(name);
	 }
	 catch (RemoteException ex) {
	 }
	}
}
}

RemoteDaemonServlet.java

Code:
 package chatgame;
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;
import javax.servlet.*;
import javax.servlet.http.*;
public abstract class RemoteDaemonServlet extends HttpServlet
											 implements Remote {
protected Registry registry;
public void init(ServletConfig config) throws ServletException {
	try {
	 //Security Manager (ist das hier richtig geht mit dieser Zeile nicht!)
	 System.setSecurityManager(new RMISecurityManager());
	 UnicastRemoteObject.exportObject(this);
	 bind();
	}
	catch (RemoteException e) {
	 System.out.println("Problem binding to RMI registry" + e.getMessage());
	}
}
public void destroy() {
	super.destroy();
	unbind();
}
// Returns the name under which we are to be registered
protected String getRegistryName() {
	return "Chat";
}
protected int getRegistryPort() {
	try { return Integer.parseInt(getInitParameter("registryPort")); }
	catch (Exception e) { return Registry.REGISTRY_PORT; }
}
protected void bind() {
	try {
	 registry = LocateRegistry.getRegistry(getRegistryPort());
	 registry.list(); // Verify it's alive and well
	}
	catch (Exception e) {
	 registry = null;
	}
	if (registry == null) {
	 try {
		registry = LocateRegistry.createRegistry(getRegistryPort());
	 }
	 catch (Exception e) {
		System.out.println ("Could not get or create RMI registry on port " +
			getRegistryPort() + ": " + e.getMessage());
		return;
	 }
	}
	try {
	 registry.rebind(getRegistryName(), this);
	 //Alternativ(geht auch nicht)Naming.rebind("rmi://172.183.247.200:1099/Chat",this);
	}
	catch (Exception e) {
	 System.out.println("Could not bind to RMI registry: " + e.getMessage());
	 return;
	}
}
protected void unbind() {
	try {
	 if (registry != null) {
		registry.unbind(getRegistryName());
		//Naming.unbind("rmi://172.183.247.200:1099/Chat");
	 }
	}
	catch (Exception e) {
	 System.out.println("Problem unbinding from RMI registry");
	}
}
}
Wie gesagt, der Server wird zusammmen mit Tomcat gestartet, also die init-Methode in ChatServlet.java...
Wahrscheinlich ist da irgendwo ein dummer Fehler...

edit:
ach ja in der zeile:
//Alternativ(geht auch nicht)Naming.rebind("rmi://172.183.247.200:1099/Chat",this);
muss die ip natürlich immer geändert werden, hatte da immer meine Internet-IP eingetragen
 
Ok hab das Problem mal gelöst, der hat meine lokale IP genommen, und versucht zu der zu verbinden, dann hab ich meine lokale IP einfach mal auf meine Internet IP gestellt (dürfte eigentlich gar nciht gehen) und dann klappt es...

Aber eine kleine Frage hab ich noch, kann es sein, das RMI nicht mit einem Router funktioniert
 
Solange der Router die entsprechenden Ports weiterleitet (forwarded) sollte es gehen, denke ich .. Der Transport ist ja dann Aufgabe von TCP/IP ..
 
Ja aufm Server ist das klar aber ich meinte jeztz für die Clients..

edit:
Also ich meine aufm Server ist das ja Port 1099 aber bei den Clients weiß man den Port ja gar nicht läuft ja alles intern
 
Zuletzt bearbeitet:
Zurück