Java - Socketbasierter MultiThread Chatserver

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Java - Socketbasierter MultiThread Chatserver

    Hallo zusammen,

    ich versuche mich gerade an einem Chatserver in Java und komme leider überhaupt nicht weiter. Der Server läuft über die ServerSocket-Klasse und soll, wie es sich für einen Chat gehört, natürlich mehrere Clients gleichzeitig bedienen. Also versuche ich das mit Threads zu lösen.

    Was ich bisher habe:

    Code:
    /* Chatserver java */
    
    import java.net.*;
    import java.io.*;
    
    public class ChatServer
    
      // Anfang Attribute
      // Ende Attribute
    
    {
    
      // Anfang Methoden
      public static void main(String[] args)
      {
        int cnt = 0;
        try {
          System.out.println("Warte auf Verbindungen auf Port 4000...");
          ServerSocket echod = new ServerSocket(4000);
          while (true) {
            Socket socket = echod.accept();
            (new ChatClientThread(++cnt, socket)).start();
          }
        } catch (IOException e) {
          System.err.println(e.toString());
          System.exit(1);
        }
      }
      // Ende Methoden
    }
    
    class ChatClientThread
    extends Thread
    {
    
      // Anfang Attribute1
      private int    verbindungsnummer;
      private Socket socket;
      // Ende Attribute1
    
    
      public ChatClientThread(int verbindungsnummer, Socket socket)
      {
        this.verbindungsnummer   = verbindungsnummer;
        this.socket = socket;
      }
    
      // Anfang Methoden1
    
      public void run()
      {
        String msg = "Chatserver: Verbindung hergestellt";
        System.out.println(msg);
    
        try {
          InputStream in = socket.getInputStream();
          OutputStream out = socket.getOutputStream();
          out.write((msg + "\r\n").getBytes());
          int c;
          while ((c = in.read()) != -1) {
            out.write((char)c);
            System.out.print((char)c);
          }
          System.out.println("Verbindung " + verbindungsnummer + " wird beendet");
          socket.close();
        } catch (IOException e) {
          System.err.println(e.toString());
        }
      }
      // Ende Methoden1
    }
    Als Client verwende ich Flash, was so eigentlich auch ganz gut funktioniert.
    Mein Problem ist, das mit diesem Script bisher zwar beliebig viele Clients auf dem Server einloggen können, aber der Server eher als Echo-Server fungiert, da er jedem Client nur das gesendete wieder zurücksendet und eben auch nur dem der gesendet hat...nicht gerade sehr sinnvoll

    Ich wollte nun die Sockets in einem array speichern und dann nacheinander jedem Clienten die eingehenden Messages senden, aber irgendwie klappt das nicht. Sobald ich irgendwie die im try-block der run()-Methode etwas verändere, kann ich weder senden noch empfangen.

    Ich möchte jetzt eigentlich nur, das der Client identifiziert wird (er sendet beim Verbindungsaufbau eine Kennung - seinen Usernamen) und das er in einer Liste gespeichert wird, damit ich dann eine Art Clientpool verwalten kann...Ich hab es auch schon mit der Vector-Klasse probiert...ohne grossen Erfolg.

    Ich muss dazu sagen, das ich noch nicht allzu bewandert bin was Java betrifft und daher meine Schwierigkeiten habe.

    Ich wäre dankbar, wenn mir mal jemand etwas auf die Sprünge helfen könnte...ich habe schon so ziemlich das ganze Wochenende damit verbracht, aber bin immer nur mit Fehlern belohnt worden...

    Gruß
    -=Es gibt Leute, die können Ihren Stammbaum bis zu denen zurückverfolgen, die noch darauf saßen=-

  • #2
    Ohne synchronized wird das nichts. Google das mal!

    http://www.acm.org/crossroads/xrds6-1/ovp61.html

    Kommentar


    • #3
      Super, das hilft enorm, danke dir So langsam nimmt es gestalt an ....
      Im Code bei dem Link gibt es allerdings ein entscheidendes Problem: der Server wirft eine NullPointerException in Zeile 66 aus und die wird auch nicht aufgefangen, wenn der Client die Verbindung nicht mit "/Quit" beendet. Das ist aber ja nicht immer möglich, z.B. bei einem Verbindungsabbruch...Wieso fängt IOException ioe dies nicht auf und wie oder an welcher Stelle kann man das ändern ??

      Gruss
      Zuletzt geändert von ZuLtAn; 31.08.2009, 12:03.
      -=Es gibt Leute, die können Ihren Stammbaum bis zu denen zurückverfolgen, die noch darauf saßen=-

      Kommentar


      • #4
        Welche ist denn Zeile 66, ich habe keine Lust zu zählen. Außerdem wäre es besser, wenn du deinen Code postest. Der sieht ja sicherlich schon nicht mehr so aus wie auf der verlinkten Seite.

        Kommentar


        • #5
          Ok, also dies ist mal meine ChatHandler Klasse, jetzt ist die Zeile der Exception allerdings 75, da ich ja was verändert habe. Es ist aber immer die While-Schleife, in der die Nachrichten an alle Clienten gesendet werden.

          Code:
          class ChatHandler extends Thread {
            static Vector handlers = new Vector( 10000 );
            private boolean registered = false;
            private String username;
            private Socket socket;
            private BufferedReader in;
            private PrintWriter out;
          
              public ChatHandler(Socket socket) throws IOException {
                  this.socket = socket;
            in = new BufferedReader(
                new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(
                new OutputStreamWriter(socket.getOutputStream()));
              }
              public void run() {
              String line;
          
            synchronized(handlers) {
                handlers.addElement(this);
           // add() not found in Vector class
            }
            try {
            if (registered == false){
                username=in.readLine();
                out.println("Angemeldet als "+username);
                out.flush();
                registered=true;
                }
                while(!(line = in.readLine()).equalsIgnoreCase("/quit")) { // Dies ist Zeile 75
              for(int i = 0; i < handlers.size(); i++) {
                synchronized(handlers) {
                          ChatHandler handler =
                        (ChatHandler)handlers.elementAt(i);
                      handler.out.println(username+": "+line + "\r");
                handler.out.flush();
                }
              }
                }
            } catch(IOException ioe) {
                ioe.printStackTrace();
            } finally {
                try {
              in.close();
              out.close();
              socket.close();
                } catch(IOException ioe) {
                } finally {
              synchronized(handlers) {
                  handlers.removeElement(this);
              }
                }
            }
              }
          }
          Der Server läuft allerdings problemlos weiter, alle anderen Clients können normal weiter kommunizieren und es können sich auch nach der Exception weiterhin neue Clients anmelden...

          Der genaue Fehler lautet (wird auch nur in der Konsole angezeigt und nicht an die Clienten weitergegeben):

          Exception in thread "Thread-0" java.lang.NullPointerException at ChatHandler.run<ChatServer.java:75>

          Ich hab zuerst gedacht, das es evtl. diese Zeile ist,die die Exception auswirft...ist aber nicht der Fall:

          Code:
          ...
          } catch(IOException ioe) {
                ioe.printStackTrace();
            } finally {
          ...
          -=Es gibt Leute, die können Ihren Stammbaum bis zu denen zurückverfolgen, die noch darauf saßen=-

          Kommentar

          Lädt...
          X