TCP/IP: Frage zu ServerSocket

  • Ich verstehe zwar jetzt nicht ganz was du gemacht hast, aber es funktioniert prinzipiell immer ohne Probleme dass du dir eine Klasse schreibst die von Component oder JComponent erbt und dort die Methode paint() überschreibst. Poste am besten mal den Code.

    There's no better place than 127.0.0.1!

  • Danke auch dir für die Antwort.
    Ich hatte aber wie ich gesehen habe einen andern Denkfehler. Durch Überlagern der paintComponent Methode sorge ich jetzt automatisch dafür, dass mein Spielfeld immer sichtbar ist.

  • Jetzt habe ich noch ein Problem mit meinem Projekt ^^. Habe in meinem Gui ein JLabel von dem ich will, dass es den Text ZENTRIERT darstellt. Habe dafür folgendes getan:

    Code
    dasVerfluchteLabel.setHorizontalTextPosition(SwingConstants.CENTER);


    Trotzdem wird der Text LINKSBÜNDIG angzeigt.
    Kann mir das jemand erklären? ^^

    Danke wie immer im Voraus

  • Jetzt habe ich noch ein Problem mit meinem Projekt ^^. Habe in meinem Gui ein JLabel von dem ich will, dass es den Text ZENTRIERT darstellt. Habe dafür folgendes getan:

    Code
    dasVerfluchteLabel.setHorizontalTextPosition(SwingConstants.CENTER);


    Trotzdem wird der Text LINKSBÜNDIG angzeigt.
    Kann mir das jemand erklären? ^^

    Danke wie immer im Voraus

    Jetzt mal spontan aus dem Bauch heraus: Ich hatte folgendes Konstrukt in Erinnerung:

    Code
    dasVerfluchteLabel.setHorizontalAlignment(SwingConstants.CENTER);

    ...oder so weiß es nicht mehr auswendig, such mal nach so einer ähnlichen Methode.

    There's no better place than 127.0.0.1!

    Einmal editiert, zuletzt von java-girl (21. Dezember 2008 um 20:44)

  • Und wieder macht mir Java Ärger.
    Ich möchte für das Spiel Statistiken anlegen, wer gegen wen wie oft gewonnen/verloren/unentschieden ... etc. Zu diesem Zwecke hab ich eine Klasse ClientData entworfen mit ein paar Attributen. In meiner Server Klasse habe ich jetzt einen Vektor dem ich ClientData hinzufüge.
    Jetzt das Problem.
    Wenn ich den leeren Vektor versuche abspeichern zu lassen (ObjectOutputStream) läuft meine Methode wunderbar (neuer OutputStream, dann writeObject, dann close). Auch das lesen funktioniert dann wunderbar. Wenn ich aber 1 Element hinzufüge (oder auch mehr) dann passiert folgendes im Debugger: Er springt auf die writeObject() Methode, dann klick ich auf nächster Schritt und der Debugger springt aus dem Try-Statement heraus, ohne auf close() zu springen und ohne auf die Exceptions zu springen (catch Statements FileNotFound, ClassNotFound, IO). Beim Lesen erzeugt er dann auch erst brav einen neuen ObjectInputStream, dann springt er auf die readObjectMethode(). Beim drücken auf weiter im Debugger springt er ebenfalls aus dem try-Statement raus und das eigentlich ausgelesene Objekt ist null!
    Was kann an einem Vektor falsch sein, dass ObjectStreams da so einen Fehler bauen, die reinen Datei Lese und Schreib Methoden verwende ich schon seit Jahren, hab mir da ne Klasse angelegt gehabt mit allen möglich nützlichen Methoden.

    Danke wie immer im Vorraus


  • Was kann an einem Vektor falsch sein, dass ObjectStreams da so einen Fehler bauen, die reinen Datei Lese und Schreib Methoden verwende ich schon seit Jahren, hab mir da ne Klasse angelegt gehabt mit allen möglich nützlichen Methoden.

    AFAIK müssen Objekte, die du mit einem ObjectStream schreibt, das Interface Serializable implementieren. Vermutlich tut das dein Objekt nicht bzw. schätze ich dass nur das Vector-Object rausgeschrieben wird, und die anderen Objekte einfach generell nicht. Deswegen rate ich dir ausdrücklich davon ab, deine Daten auf diese Art und Weise zu speichern. Für so etwas entwirft man sich immer einen eigenen Dokumenttyp für den man dann einen Parser schreibt. Oder einfach ausgedrückt: schreibs in eine Textdatei.

    There's no better place than 127.0.0.1!

    2 Mal editiert, zuletzt von java-girl (23. Dezember 2008 um 10:43)

  • AFAIK müssen Objekte, die du mit einem ObjectStream schreibt, das Interface Serializable implementieren. Vermutlich tut das dein Objekt nicht bzw. schätze ich dass nur das Vector-Object rausgeschrieben wird, und die anderen Objekte einfach generell nicht.

    Wenn eine Instanz einer Klasse verwendet wird, die Serializable nicht implementiert, wird eine NotSerializableException geworfen.

    Deswegen rate ich dir ausdrücklich davon ab, deine Daten auf diese Art und Weise zu speichern. Für so etwas entwirft man sich immer einen eigenen Dokumenttyp für den man dann einen Parser schreibt. Oder einfach ausgedrückt: schreibs in eine Textdatei.

    Unsinn. Serialisierung ist - wenn man nur Java verwendet - ein tolles Feature, warum sollte man sie nicht verwenden? Wenn die Daten beim Einlesen unbrauchbar sind oder nicht zu der Java-Klasse passen, bekommst du eine entsprechende Exception. Sich ein Dokumentenformat ausdenken und dafür Ein-/Ausgabemodule schreiben, das ist nur unnötiger Bloat und eine Fehlerquelle.

  • Unsinn. Serialisierung ist - wenn man nur Java verwendet - ein tolles Feature, warum sollte man sie nicht verwenden?

    Mir wurde von jemandem davon abgeraten, dessen Meinung ich sehr schätze.

    Außerdem muss man ja bei einem Vector den Aufwand betreiben, jedes enthaltene Objekt einzeln rauszuschreiben.

    There's no better place than 127.0.0.1!

  • Mir wurde von jemandem davon abgeraten, dessen Meinung ich sehr schätze.

    Überzeugendes Argument.

    Außerdem muss man ja bei einem Vector den Aufwand betreiben, jedes enthaltene Objekt einzeln rauszuschreiben.

    Blödsinn.


    Ausgabe:

    Code
    a
    b
    c
  • Also... alle Objekte im Vektor sind nicht serialized. Könnte es daran liegen? Ich versuch es einfach mal. Denn der Vektor enthält relativ VIELE verschiedene Informationen ^^ könnte wirklich sehr aufwendig werden mit dem Parser.

  • Denn der Vektor enthält relativ VIELE verschiedene Informationen ^^

    D.h. da ist einmal ein Integer drin, einmal ein String, einmal ein Date? Das ist nicht schön. Da fehlt nämlich jegliche Typinformation.

    Ein Programmierfehler könnte dazu führen, dass ein völlig falsches Objekt in den Vektor eingefügt wird; dieses Problem wird vom Compiler nie erkannt und tritt daher erst zur Laufzeit zu Tage. Es hat vielleicht ganz andere Auswirkungen als man vermuten würde und ist die Ursache ist daher schwer zu lokalisieren.

    Lösung: Strukturiere die Daten.


    Variante 1: Nehmen wir an, du hast Integers, Strings und Dates, die du jetzt alle in einem Vector speicherst. Zerteile diesen Vector in drei Vectors, wobei jeder Vector nur Elemente eines einzigen Typs speichert. Weiters brauchst du eine Klasse, welche nichts anderes macht als eben diese drei Vectors als Instanzvariablen zu haben:

    PHP
    public class MyData {
        private Vector<String> stringVector;
        private Vector<Integer> integerVector;
        private Vector<Date> dateVector;
    }


    Da musst du dir dann noch überlegen, wie der Zugriff auf diese drei Variablen funktionieren soll (in meinem Vorschlag sind sie ja private, damit von außen nicht direkt auf den Zustand eines Objekts vom Typ MyData zugegriffen werden kann).

    Wenn du das Problem so angehst, hast du drei Listen in denen wirklich nur Objekte der gewünschen Typen enthalten sind. Alles andere führt zu Compilerfehlern (solange du nicht sinnlos herumcastest).


    Variante 2: Du hast Informationen unterschiedlicher Typen, für die es einen gemeinsamen Oberbegriff gibt. In diesem Fall kannst du eine abstrakte Klasse (oder ein Interface) als Repräsentation dieses Oberbegriffs definieren und Klassen für speziellere Informationen davon ableiten. In deinem Vector speicherst du dann Instanzen der abstrakten Klasse (bzw. des Interfaces).

    Nehmen wir an, wir wollen Informationen speichern, wie auf einen bestimmten Dienst zugegriffen werden kann. Da gibt es zum Beispiel die Möglichkeit des Zugriffs über TCP, da brauchst du IP-Adresse/Hostname und Port; andererseits gibt es die Möglichkeit des Zugriffs über UDP, auch mit IP-Adresse/Hostname und Port. Diese Daten wollen wir alle in einem Vector speichern.

    Dazu definieren wir einmal eine abstrakte Klasse:

    PHP
    public abstract class AccessInformation {
    }


    und dann zwei Klassen, eine für TCP-Informationen und eine für UDP-Informationen:

    PHP
    public class TCPAccessInformation extends AccessInformation {
        private InetAddress host;
        private int port;
    }
    PHP
    public class UDPAccessInformation extends AccessInformation {
        private InetAddress host;
        private int port;
    }


    Der Vector, in dem wir die Daten speichern, ist dann ein Vector<AccessInformation>. In diesem Vector können wir Instanzen der Typen TCPAccessInformation sowie UDPAccessInformation speichern, sonst nichts.

    Der Unterschied zwischen TCPAccessInformation und UDPAccessInformation ist hier nicht wirklich gravierend. Das ganze ist aber erweiterbar; wenn beispielsweise der Zugriff auf den Dienst auch über ein Webservice möglich ist, könnte man eine weitere Klasse von AccessInformation ableiten, welche die entsprechenden Zugriffsdaten (eine URL einer WSDL) kapselt. Auch diese kann man dann in unserem Vector speichern.


    So, jetzt hab ich aber genug geschwafelt. Ich hoffe, ich habe endgültig alle Klarheiten beseitigt.

  • Wow... d.h. ich kann nicht einfach meine Klasse Data in den Vektor packen? Denn der Vektor an sich enthält nur ClientData Objekte, diese aber enthalten dann Strings, ints, Vectors.... Gibt es keine Möglichkeit diese Klasse zu nehmen?

  • Ok, das mit der Serialization hat tatsächlich geklappt... ich denke mal ich werde, um den Aufwand gering zu halten, das jetzt so verwenden.
    Danke allen, die an der Lösung dieses Problemes geholfen haben und ein Frohes Fest.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!