Archief - [PROG]JAVA RMI probleem

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

NaaiT

Legacy Member
hi,

ik ben voor school een p2p-programma aan het schrijven, en werk hiervoor met java RMI.
Nu is het gelukt om connectie tussen client & server te krijgen, maar zit ik met volgend erg eigenaardig probleem:

stel: er staat 1 server op & 10 clients. Deze zijn allemaal zonder problemen geconnecteerd met de server. Client 2,3,...,10 kan ik allemaal afsluiten. Erna kan ik ook nog andere clients bijzetten.
Nu ligt het probleem bij de eerste client die ik opzet: vanaf het moment ik deze afsluit, vernietigt hij blijkbaar het stub-object van de server in die server zijn register. Een registry.lookup("server") werkt dan niet meer. Mijn server is onbonden van zijn register, dus kan ik er niets meer mee aanvangen.

code server:
Code:
public class ServerInstance implements ServerInterface, ClientActionListener, ServerActionListener {
	
	/* -- Class Variables ------------------------------------------------------ */

	private static ServerInstance instance = null;
	private ExecutorService threadPool = Executors.newCachedThreadPool();
	private Boolean serverInitialized = false;
	private Boolean publicationServerInitialized = false;
	private Registry rmiRegistry;
	private Set<ServerActionListener> listeners = new HashSet<ServerActionListener>();

	/* -- Constructors --------------------------------------------------------- */
		
	protected ServerInstance(ServerActionListener parent, String sName, String sPort, String publisherPort) {		
		if(parent!=null)
			addServerActionListener(parent);
		setUpRegistry();
		if(validateServer(sName, sPort))
			setUpServer();
	}

	/* -- Singleton Pattern ---------------------------------------------------- */
	
	public static ServerInstance getInstance() {...	}
	
	public static void stopInstance() {
		if(instance!=null)
			instance.stopServer();
	}

	/* -- Actions -------------------------------------------------------------- */
	
	private void setUpRegistry() {
		try {
			rmiRegistry = LocateRegistry.createRegistry(Config.getInstance().getDefaultRMIPort());
        } 
		catch (RemoteException ex) {
            /* registry already existed on this machine, so connect to it */
            try {
                rmiRegistry = LocateRegistry.getRegistry(Config.getInstance().getDefaultRMIPort());
            } 
            catch (RemoteException re) {
            	toConsole(ServerAction.NOTIFY, "Error creating RMI registry.");
            }
        }
	}
	
	private boolean validateServer(String sName, String sRMI) {	...
Config.getInstance().getThisServerStatus().resetServerStatus(sName, sRMI);
		return true;
	}
	
	private void setUpServer() {
        try {
        	/* Export ServerInstance */
			ServerInterface stub = (ServerInterface) UnicastRemoteObject.exportObject(this, 0);
			rmiRegistry.rebind(Config.getInstance().getThisServerStatus().getServerRMI(), stub);
            toConsole(ServerAction.INITIALIZED, "Server up & running.");            
            serverInitialized = true;
        } 
        catch (RemoteException ex) {
        	toConsole(ServerAction.CRASH, "Failed to create server on virtual port \"" + Config.getInstance().getThisServerStatus().getServerRMI() + "\". Please try an other one.");
        }
	}
	
	private void stopServer() {
		/* unbind the server stub */
		try {
			rmiRegistry.unbind(Config.getInstance().getThisServerStatus().getServerRMI());
		}
		catch (Exception ae) {
			toConsole(ServerAction.CRASH, "Failed to close server on virtual port \"" + Config.getInstance().getThisServerStatus().getServerRMI() + "\".");
		}

		/* server stopped successfully */
		toConsole(ServerAction.CRASH, "Server crashed by user.");
	}

	/* -- Remote Actions ------------------------------------------------------- */
	public String sayHello() { // remark: no throws clause!
		return "Hello, world!";
	}
	
	/* -- Events --------------------------------------------------------------- */
	...
}

code client:
Code:
public class ConnectionToServer {
	
	/* -- Class Variables ------------------------------------------------------ */

	private String serverIP = null;
	private String serverRMI = null;
	private Integer clientIDAtServer = null;
	private ServerInterface stub = null;
	private boolean serverInitialized = false;
	private Set<ConnectionActionListener> listeners = new HashSet<ConnectionActionListener>();
	
	/* -- Constructors --------------------------------------------------------- */

	public ConnectionToServer(ConnectionActionListener parent, String sName, String sRMI) {	
		addConnectionActionListener(parent);
		if(validateServer(sName, sRMI))
			retrieveServerStub();
		removeConnectionActionListener(parent);
	}

	/* -- Actions -------------------------------------------------------------- */

	private boolean validateServer(String sName, String sRMI) {...}
	
	private void retrieveServerStub() {
		/* local variables */
		Registry rmiRegistry;
		
		try {
			rmiRegistry = LocateRegistry.getRegistry(serverIP.toString(), Config.getInstance().getDefaultRMIPort());
			stub = (ServerInterface) rmiRegistry.lookup(serverRMI);
			toConsole(ConnectionAction.CONNECTED, "Connected to server " + serverIP + ":" + serverRMI + ".");
		} 
		catch (Exception e) {
			toConsole(ConnectionAction.DISCONNECTED, "Failed to contact server " + serverIP + ":" + serverRMI + ".");
			e.printStackTrace();
		}
	}
	
	/* -- Remote Actions ------------------------------------------------------- */
	
	...

	/* -- Events --------------------------------------------------------------- */
	...
}

error NA het sluiten van client1, en het terug opvragen van de serverstub:
Code:
java.rmi.NotBoundException: SERV
	at sun.rmi.registry.RegistryImpl.lookup(Unknown Source)
	at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
	at sun.rmi.server.UnicastServerRef.oldDispatch(Unknown Source)
	at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
	at sun.rmi.transport.Transport$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.rmi.transport.Transport.serviceCall(Unknown Source)
	at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
	at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
	at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
	at sun.rmi.server.UnicastRef.invoke(Unknown Source)
	at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
	at p2pClient.io.ConnectionToServer.retrieveServerStub(ConnectionToServer.java:69)
	at p2pClient.io.ConnectionToServer.<init>(ConnectionToServer.java:35)
	at p2pClient.gui.ClientMainPanel.setUpServer(ClientMainPanel.java:190)
	at p2pClient.gui.ClientMainPanel.access$2(ClientMainPanel.java:183)
	at p2pClient.gui.ClientMainPanel$3.actionPerformed(ClientMainPanel.java:148)
	at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
	at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
	at org.jvnet.substance.utils.RolloverButtonListener.mouseReleased(RolloverButtonListener.java:110)
	at java.awt.Component.processMouseEvent(Unknown Source)
	at javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.awt.Component.processEvent(Unknown Source)
	at java.awt.Container.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)

Iemand enige ideetjes? want ik word er allesinds zot van :(

thx

Sven

NaaiT

Legacy Member
hm blijkbaar ligt het aan het volgende:

Code:
private void setUpRegistry() {
		try {
			rmiRegistry = LocateRegistry.createRegistry(Config.getInstance().getDefaultRMIPort());
        } 
		catch (RemoteException ex) {
            /* registry already existed on this machine, so connect to it */
            try {
                rmiRegistry = LocateRegistry.getRegistry(Config.getInstance().getDefaultRMIPort());
            } 
            catch (RemoteException re) {
            	toConsole(ServerAction.NOTIFY, "Error creating RMI registry.");
            }
        }
	}

Die code werkt wel, maar blijkbaar gaat de 1ste client (deze die dus nog het register moet aanmaken) bij close dat register wegwerpen. Andere clients/servers die ondertussen van dat register gebruik maken, functioneren dus ook niet meer.

Hoe kan ik ervoor zorgen dat dit register blijft openstaan, als ik die eerste client dan verwijder?

Misschien kan ik het register aanmaken vooraleer ik clients/servers opzet, maar dat vind ik maar een omslachtige methode :(

maxdevis

Legacy Member
even offtopic:
maar een p2p netwerk heeft toch normaal geen servers?
of ben ik mis?

NaaiT

Legacy Member
mja gebt dus wel ne server nodig waar ge alle info van de clients gaat stockeren. Via de server kan je dus zien wat er allemaal geshared wordt op het netwerk, zoeken naar bepaalde dingen etcetc.. Eens ge effectief vraagt om iets te downloaden, werkt dat dan inderdaad via een gewoon tcp-verbindingske tussen 2 clients.

tmagus

Legacy Member
maxdevis zei:
even offtopic:
maar een p2p netwerk heeft toch normaal geen servers?
of ben ik mis?

offtopic antwoord...u hebt gelijk :p
Volledig gedecentraliseerde p2p netwerken

Volledig gedecentraliseerde p2p netwerken
In een volledig gedecentraliseerd p2p netwerk is er geen enkele server die iets doet, maar verloopt het contact volledig peer-to-peer. De computers staan in direct contact met elkaar zonder een server ertussen. Het contact wordt gelegd door het sturen van berichten naar een vooraf afgesproken netwerkpoort. Door middel van een PING (Packet InterNet Groper) wordt een andere computer opgeroepen waarvan bekend is dat deze vaak online is. De nieuwe gebruiker staat in direct contact met deze computer (host), welke op zijn beurt weer een directe verbinding heeft met degene met wie hij contact heeft gelegd. Enzovoort. Bekende voorbeelden in deze categorie zijn KaZaA en BitTorrent.

Nog wa meer uitleg:

Gedecentraliseerde p2p-netwerken
Servent
Gedecentraliseerde p2p-programma's worden ‘servents’ genoemd. Een servant is tegelijk server en cliënt. Wie een bijvoorbeeld een Gnutella-kloon op zijn computer installeert, krijgt daarmee zowel een zoekmachine als een bestandsserver. De zoekmachine dient om andere Gnutellianen op internet te lokaliseren en te kijken welke bestanden zij in de aanbieding hebben. De rol van bestandsserver is bedoeld om je eigen bestanden aan de Gnutella-gemeenschap beschikbaar te stellen. Wat je precies aanbiedt en wat je privé wilt houden, bepaal je zelf door bepaalde mappen van je harde schijf open te stellen.
De zoektochten door gedistribueerde netwerken worden nergens vastgelegd, maar verspreiden zich als duizenden waterrimpels over dezelfde vijver. Daardoor zijn ze heel lastig tot de bron te herleiden. De anonimiteit van de surfer is bij dergelijke programma's veel groter dan bij gecentraliseerde p2p-programma's als Napster.
Vanwege dit ingebakken anarchisme beschouwen sommigen de gedistribueerde p2p-netwerken als een subversieve of zelfs ontwrichtende technologie die de wortels van het internet zouden kunnen aantasten. Anderen beschouwen de p2p-netwerken als de terugkeer naar het egalitaire en nog niet gecommercialiseerde en geconcentreerde internet van het eerste uur.
Het is en blijft een wapenwedloop tussen rebellen en de gevestigde orde. De rebellen tarten de gevestigde orde door een revolutionair gebruik van geavanceerde technologieën voor communicatie en informatie-uitwisseling. De rebellen worden door kapitaalkrachtige mediagiganten voor het gerecht gesleept en bedreigd. Met behulp van programma's als Media Tracker en Copyright Agent bespioneren platenmaatschappijen individuele gebruikers in p2p-netwerken. Houders van auteursrechten die menen dat hun rechten op internet of online diensten zijn geschonden door ongeautoriseerd gebruik van hun beschermde werken kunnen zich richten tot de betreffende service provider en eisen dat het illegale materiaal wordt verwijderd of dat de toegang daartoe wordt geblokkeerd.
Gedecentraliseerde p2p-netwerken maken geen gebruik van een centrale server om de bestanden van alle gebruikers bij te houden. De gebruiker begint met een op het netwerk aangesloten computer die is uitgerust met een 'servent' (het programma werkt als een combinatie van ‘server’ en ‘client’). De eerste gebruiker met computer A legt contact met een andere op het netwerk aangesloten computer B. A kondigt aan dat het 'alive' is voor B, welke op zijn beurt aankondigt bij alle computers waarmee het is verbonden, C,D,E en F, dat A in de lucht is. De computers C,D,E en F kondigen vervolgen aan alle computers waarmee zij zijn verbonden aan dat A in de lucht is. Deze computers herhalen het patroon en kondigen aan de computers waar zij mee verbonden aan dat A in de lucht is. Hoewel het bereik van dit netwerk potentieel oneindig is, wordt het in werkelijkheid beperkt door 'time-to-live' (TTL): dat is het aantal lagen van computers dat het verzoek zal bereiken. Servents verwerken elke netwerkboodschap die een TTL hebben die excessief hoog is.

Nadat A heeft aangekondigd dat het in de lucht is aan de diverse leden van het netwerk, kan het gaan zoeken in de inhoud van de gedeelde directories (mappen) van de netwerkleden. De zoekopdracht wordt naar alle leden van het netwerk verstuurd, beginnend met B, dan naar C,D,E,F, die het op hun beurt versturen naar de computers waarmee zij verbonden zijn, enzovoort. Wanneer een van de computers in het netwerk een bestand heeft dat beantwoordt aan het verzoek, verstuurt het de bestandsinformatie (naam, omvang, type etc.) terug via alle computers in het pad naar A. De lijst van bestanden die voldoen aan de zoekopdracht verschijnen op de servent display van computer A. A is dan in staat om een directe verbinding te leggen met de computer waarop het bestand beschikbaar is en kan dat bestand direct van die computer downloaden. Het gedistribueerde p2p-model maakt het delen van bestanden mogelijk zonder servers te gebruiken die zelf geen directe bestanden aanbieden.

Het gedecentraliseerde p2p-model heeft een aantal voordelen boven andere methoden van bestandsdeling. Omdat het netwerk gedecentraliseerd is, is het robuuster dan een gecentraliseerd model: het elimineert immers de afhankelijkheid van gecentraliseerde servers die potenti&eumlle kritieke faalpunten zijn. De nieuwe generatie p2p-netwerken maakt geen gebruik van een centrale databank met de namen van beschikbare bestanden, maar is volledig gedecentraliseerd. Daardoor is er geen spin in het web die kan worden uitgeschakeld, zoals het geval was met de 140 servers van Napster. De enige manier om deze netwerken uit de lucht te krijgen, is de miljoenen individuele gebruikers ervan voor de rechter te dagen. De nieuwe generatie p2p-programma’s is dus niet alleen vanuit technisch oogpunt robuuster, maar ook vanuit juridisch oogpunt veel moeilijker te bestrijden. Gedecentraliseerde p2p-netwerken zoals Gnutella zijn ontworpen voor het zoeken naar elk type digitaal bestand (van recepten tot plaatjes en java bibliotheken). In principe kunnen gedecentraliseerde netwerken elke computer op het internet bereiken, terwijl zelfs de meest omvangrijke zoekmachines slechts 20% van de beschikbare websites bereiken (groter bereik).

In gedecentraliseerde p2p-netwerken worden de berichten naar ‘onbekende vrienden’ verstuurd. De ene gebruiker verstuurt zijn zoekopdracht naar zijn ‘naaste vrienden’ 'naaste vrienden', die op hun beurt dat verzoek onder hun ‘vrienden-van-vrienden’ verspreiden. Wanneer een of meer gebruikers in het netwerk de verbinding verbreken, worden zoekopdrachten nog steeds doorgegeven.

tis tis een combi dat de client eigenlijk ook de server is, to make a story short...

Messias.

Legacy Member
Nja, zo'n gedecentraliseerd systeem bedenken en implementeren is natuurlijk wel nog een orde moeilijker.

NaaiT

Legacy Member
tjah je kan dit idd met gedecentraliseerde systemen oplossen, maar ik vond het toch handiger/overzichtelijker om met servers te werken :)

Hale

Legacy Member
Alleen is het dan natuurlijk geen p2p systeem meer...

verder mist dat stukje tekst natuurlijk wel een groot nadeel van de huidige p2p systemen en dat is dat de zoekalgoritmes niets anders zijn dan flooding algoritmes.

In meer gestructureerde applicaties (lees: de beheerder van de applicatie heeft inspraak in hoe de data over de verschillende machines fysiek verspreid wordt) kunnen er technieken zoals distributed hash tabels gebruikt worden om zeer efficient bestanden terug te vinden.

NaaiT

Legacy Member
bwa geen p2p meer.. de basis blijft nogaltijd het uitwisselen van bestanden tussen verschillende gebruikers, het enige dat er verandert is dat de 'administratie' grotendeels via een server verloopt.
Eens je komt tot het werkelijk uitwisselen van bestanden, zit die server er uiteraard niet meer tussen.

maxdevis

Legacy Member
mja dan is het eigenlijk meer een Direct Connect applicatie
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan