-         

Seite 1 von 4 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 38

Thema: Java Server/Plugin Manager

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    23.08.2004
    Ort
    Bremen
    Alter
    27
    Beiträge
    102

    Java Server/Plugin Manager

    Anzeige

    Hi Leute.

    Ich habe ein Problem beim Programmieren eines Java-Servers, den ich für die TCP-Kommunikation zwischen zwei Programmteilen benötige. Hier ist der Code:

    Code:
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    class Server
    implements Runnable
    {
    	public void run()
    	{
    		try
    		{
    			ServerSocket sv = new ServerSocket(4003);
    			
    			while(true)
    			{
    				if(sv.accept() != null)
    				{
    					Socket s = sv.accept();
    					Client c = new Client(s);
    				}
    			}
    		}
    		catch(IOException e)
    		{
    			System.out.println(e.getMessage());
    		}
    	}
    }
    Das Problem ist, dass der Server keine Verbindung erstellt, selbst wenn sich ein Client connectet. Wenn ich allerdings die if-Abfrage weglasse gibt es sofort eine NullPointerException, da sv.accept() ja noch null ist, solange sich kein Client verbindet. Außerdem bin ich mir nicht sicher, ob es mit der Konstruktion die ich für den Server im Moment verwende möglich ist, das sich mehrere Clients verbinden und für jeden ein neues Exemplar der Klasse Client angelegt wird.
    Danke.

    Gruß, Jan.

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    23.08.2004
    Ort
    Bremen
    Alter
    27
    Beiträge
    102
    Um den Zusammenhang besser zu verstehen hier ein kleiner Programmablauf (kleiner Tipp: das ist viel Text, nur der obere Absatz ist erstmal wichtig, weil in dem Teil des Programms der Fehler sitzt):

    Die Hauptklasse RSS erzeugt einen neuen Thread, der der Server ist. Eigentlich sollte, wenn sich ein Client, also ein Plugin, verbindet ein neues Exemplar der Klasse Client erstellt werden. Diese Client Klasse bildet die "Kommunikationsschittstelle" für das Plugin. Am Anfang schickt das Plugin einen String "identety" an seine Schnittstelle, der seine ID beinhaltet. Die Client-Klasse leitet die ID (in Form eines Integers) und sich selbst an die Funktion registerPlugin() der Hauptklasse RSS weiter. registerPlugin() fügt einem Client Array nun an der id'ten Stelle den übergebenen Client hinzu (clientarray[id] = client). (So ist gewähleistet, das später auf die Schnittstelle eines bestimmten Plugins zugegriffen werden kann)

    Die Client Klasse ist selbst auch ein Thread und startet sich nach dem registrieren des Plugins bei der Hauptklasse selbst. (siehe start())
    Die überschrieben run()-Methode, aus dem Interface Runnable beinhaltet eine endlos-Schleife, die den Input vom Plugin abfragt. Herreinkommende Strings haben das Format "id+msg" (z.B. 00hallo) als die ersten beiden Stellen sind die ID des Plugins an den die Mittelung geht und alle nachfolgenden Stellen sind die Mitteilung. Der String wird genau in diese Bestandteile zerlegt und der Methode messagePlugin() in der Hauptklasse RSS übergeben. Diese greift auf den Client-Array wieder an der id'ten Stelle zu und ruft die sendMessage()-Methode des dort gespeicherten Clients auf. Der wiederrum leitet den Nachrichten-String über den Socket an das Ziel-Plugin weiter. So können die Plugins miteinander kommunizieren.

    So, das soll der fertige Programmaufbau werden. Wie gesagt, das Problem besteht darin, das der Server-Thread eben kein Exemplar der Klasse Client erzeugt und so alles nicht funktioniert.

    Gruß, Jan.

  3. #3
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Versteh von Java nur Bahnhof.
    Aber fehlt mir da nicht ein "Listen" ? (wait client)
    mfg robert

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    23.08.2004
    Ort
    Bremen
    Alter
    27
    Beiträge
    102
    Ja, so hab ich mir das auch gedacht, allerdings hab ich keine Ahnung, wie sich das mit Java realisieren lässt, da es meines Wissens keine entsprechenden Listener für Sockets in Java gibt.

    Gruß Jan.

  5. #5
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Wird wahrscheinlich in "Serversocket" irgendwie impliziert sein.
    Nein, seh ich grad, das ist beim accept() dabei, das ist der blocker
    Ich räum' jetzt das Feld für kluge Leute mfg

    EDIT 2: Ich les, da gibt's ein open , sonst is nix mit accept

  6. #6
    Erfahrener Benutzer Roboter Genie Avatar von Hessibaby
    Registriert seit
    20.11.2003
    Ort
    Gelsenkirchen
    Alter
    65
    Beiträge
    1.597
    Hi Jan,

    tipps zum TCP-IP Stack unter Java gibt´s bei www.jcontrol.org.
    Wenn ich die Codeschnipsel richtig interpretiere fehlt das Init vom Stack aber ich bin gerade erst beim Java-Einstieg mit dieser ELV-JControll Geschichte.

    Gruß Hartmut

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    23.08.2004
    Ort
    Bremen
    Alter
    27
    Beiträge
    102
    @Hessibaby: Ich muss zugeben, ich von dem, was du da geschrieben hast nich viel verstanden Was ist das Init vom Stack?? Hört sich für mich irgendwie kompliziert an... Auf jeden Fall glaube ich das es dafür eine recht simple Lösung geben muss, weil ich ja nur darauf warten muss, dass eine Verbindung besteht.

    Weiß jemand ne Lösung dafür? Ich nehme dochmal an, das sind nicht mehr als vier Zeilen Code?!

    Gruß Jan.

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    14.12.2004
    Beiträge
    9
    Hi,

    accept() blockiert bis sich ein Client anmeldet und gibt dann einen Socket zurück.
    Dein Code wartet auf zwei Clients, das erstemal in der if-Abfrage, das zweite mal innerhalb des Anweisungsblock der if-Abfrage.
    Die if Abfrage ist also überflüssig, die NullPointerException muss eine andere Ursache haben.
    Könnte z.B daran liegen, dass s und c lokale Objekte sind, die vom GarbageCollector gelöscht werden,
    wenn der nächste Durchlauf der while Schleife einsetzt. Folgendes sollte also funktionieren:

    Code:
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    class Server
    implements Runnable
    {
       public void run()
       {
          Client c;
    
          try
          {
             ServerSocket sv = new ServerSocket(4003);
             
             while(true)
             {
                
                    c = new Client( sv.accept() );
                
             }
          }
          catch(IOException e)
          {
             System.out.println(e.getMessage());
          }
       }
    }
    Damit du mehrere Clients bedienen kannst,
    muss dein Client-Objekt einen neuen Thread erstellen, sollte also von Thread abgeleitet werden.

    Gruß, Dirk

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    23.08.2004
    Ort
    Bremen
    Alter
    27
    Beiträge
    102
    Hi.

    Vielen Dank!
    Client ist bereits ein Thread, soweit hab ich auch schon gedacht.
    Das c eine lokale Variable war, war eigendlich Absicht, denn ich dachte, da jedes c unabhängig von dem davor/danach ist, macht es druchaus Sinn, dass c nach jedem Durchlauf gelöscht wird. Naja, ich werde das jetzt mit deinem Code ausprobieren. Danke nochmal!

    Gruß Jan.

    P.S.: Bei deinem Code fällt der Import von java.net.Socket übrigens weg

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    23.08.2004
    Ort
    Bremen
    Alter
    27
    Beiträge
    102
    Hi.

    Ich hab das jetzt ausprobiert. Leider war das nicht die Lösung, die NullPointerException besteht weiterhin. Aber das hattest du ja schon vermutet.
    Ich hab mir das jetzt mal genauer angeguckt: Die Exception tritt immer dann auf, wenn die Verbindung hergestellt wird, also der ClientSocket eine Anfrage sendet. Die Ausgabe lautet:

    Exception in thread "Thread-2" java.lang.NullPointerException
    at main.Client.<init>(Client.java:23)
    at main.Server.run(Server.java:18)
    at java.lang.Thread.run(Thread.java:595)


    Die betreffenden Zeilen sind in Client.java:

    in = new BufferedReader(new InputStreamReader(s.getInputStream()));

    Also die Initialisierung eines BufferedReader, der den InputStream des Sockets ausließt.

    In Server.java:

    c = new Client(sv.accept());

    (siehe Oben)

    und in java.lang.Thread:

    public void run() {
    if (target != null) {
    target.run();
    }
    }

    Letzeres finde ich recht seltsam?! Wenn ich das richtig verstehe gibt es also ein Problem beim starten des Threads? Ich hab hier jetzt mal den Code von Client.java hochgeladen:

    Code:
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintStream;
    import java.net.Socket;
    
    public class Client
    implements Runnable
    {
    	private Socket s;
    	private Thread t;
    	private BufferedReader in;
    	private PrintStream out;
    	private int id;
    	
    	public Client(Socket s)
    	{
    		try
    		{
    			s = this.s;
    			in = new BufferedReader(new InputStreamReader(s.getInputStream()));
    			out = new PrintStream(s.getOutputStream());
    			
    			String identety = in.readLine();;
    			id = Integer.parseInt(identety.substring(0,2));
    			
    			start();
    		}
    		catch(IOException e)
    		{
    			System.out.println(e.getMessage());
    		}
    	}
    	
    	public final int getID()
    	{
    	   return id;
    	}
    	
    	public void sendMessage(String msg)
    	{
    		out.print(msg);
    	}
    	
    	private void start()
    	{
    		RSS.registerPlugin(getID(), this);
    		
    		t = new Thread(this);
    		t.start();
    	}
    	
    	private void end()
    	{
    		try
    		{
    			RSS.unregisterPlugin(id);
    			s.close();
    			t.join();
    		}
    		catch(IOException e)
    		{
    			System.out.println(e.getMessage());
    		}
    		catch(InterruptedException e)
    		{
    			System.out.println(e.getMessage());
    		}
    	}
    	
    	public void run()
    	{
    		try
    		{
    			while(s.isConnected() == true)
    			{
    				String input = in.readLine();
    				int tgid = Byte.parseByte(input.substring(0,2));
    				String msg = input.substring(2);
    				RSS.messagePlugin(tgid,msg,id);
    			}
    			
    			if(s.isClosed() == true)
    				end();
    			else
    				run();
    		}
    		catch(IOException e)
    		{
    			System.out.println(e.getMessage());
    		}
    	}
    }
    Wie man sieht implementiert Client.java das Interface Runnable, also ist es ein Thread.
    Könnte das Problem darin bestehen, das ich ein neues Client-Object anlege, es aber nicht als Thread starte?

    Naja, ich hoff mal mir kann da jemand weiterhelfen.
    Danke.

    Gruß, Jan.

Seite 1 von 4 123 ... LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •