TCP/IP: Frage zu ServerSocket

  • Hallo

    Bei meinem aktuellen Programm (ein Minispiel für mich und meine Freunde) möchte ich einen "Server" programmieren der bis ich ihn per GUI stoppe ununterbrochen an einem Port horcht ob ein Eingangssignal kommt.
    Habe mir dazu folgendes überlegt:
    Neben der Hauptklasse Server wird für jeden angemeldeten User ein Thread eröffnet der dann in einer while-Schleife die auf eine boolean Variable zurückgreift (für meine Frage ist nur der Zustand true von Bedeutung). Das "Horchen" sieht folgendermaßen aus:

    Code
    while(prüfen eines Boolean Attributes) {
          try {
            input = in.readLine();   //in ist ein BufferedReader vom Socket
            //Code der input auswertet
     
          } catch (IOException e) {
            System.out.println(e);
          }


    Meine erste Frage ist:
    [INDENT]Wenn der input gerade Ausgewertet wird, aber zugleich ein neuer String gerade eintrifft, geht dieser String dann verloren? Oder wartet der in einer Art Warteschleife, bis die Methode ausliest?
    [/INDENT]Meine zweite Frage ist:
    [INDENT]Wenn gerade kein input ankommt. Was macht die Methode? Wenn sie dann zich mal die Methode durchrattert, kann es dann passieren, dass Resourcen des Host-Rechners stark beansprucht werden?
    [/INDENT]Vielen, vielen Dank schonmal im Vorraus


    Nicholas

  • du verwendest einen BufferedReader, der hat - wie der name es schon vermuten lässt - einen puffer in dem die daten des zugrundeliegenden streams gepuffert werden. außerdem haben auch sockets einen puffer. somit sollte also nichts verloren gehen.

    bei readline wartet der bufferedreader solange, bis entweder eine neue zeile vorhanden ist oder der stream geschlossen wird. resourcen werden dabei nicht beansprucht.

    "All through my life I've had this strange unaccountable feeling that something was going on in the world, something big, even sinister, and no one would tell me what it was."
    "No," said the old man, "that's just perfectly normal paranoia. Everyone in the Universe has that."

    😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐😒😓😔😖😘😚😜😞😠😡😢😣😥😨😩😪😫😭😰😱😲😳😵😶😷

  • Wenn der input gerade Ausgewertet wird, aber zugleich ein neuer String gerade eintrifft, geht dieser String dann verloren? Oder wartet der in einer Art Warteschleife, bis die Methode ausliest?

    Letzteres. Da wird brav Zeile für Zeile eingelesen.

    Wenn gerade kein input ankommt. Was macht die Methode? Wenn sie dann zich mal die Methode durchrattert, kann es dann passieren, dass Resourcen des Host-Rechners stark beansprucht werden?

    Nein. readLine() blockiert so lange, bis eine ganze Zeile als Input vorliegt.

  • Hab jetzt glaub ich eher generell mal eine Frage zu meinem Projekt... auch bezogen auf Socket und den Kram.

    Ich hatte es mir eigentlich so vorgestellt, dass mein "Serverprogramm" aus einem Gui und einer server.java besteht, die alles bearbeiten. Jetzt sollte beim Aufruf der Methode zum Verbindungsaufbau ein neuer Thread erstellt werden, der nach neuen Verbindungen horcht. Hierbei übergibt die server.java sich selbst (this) an den Thread, damit dieser auf ihn zugreifen kann. Der Thread wartet jetzt mit der Methode accept() bis eine Verbindung aufgebaut wird und ruft dann einen neuen Thread (selbe Klasse versteht sich) der wiederum auf eine eingehende Verbindung wartet während der Ursprungsthread mit der eingegangenen Verbindung kommuniziert.

    Wenn ich jetzt das Gui starte und auf den Button Server bereitstellen klicke, dann friert mein Gui ein. Aber eigentlich sollte nach dem Drücken nur ein neuer ServerSocket erstellt werden und einer dieser ListenThreads sollte erstellt und die Methode run() aufgerufen werden.
    Kommentiere ich die ThreadZeile aus friert das Gui nicht. Deshalb muss es wohl am Thread liegen.
    Aber eigentlich hatte ich ja extra dieses warten auf weitere Clients in einen Thread gepackt, damit der Rest (das Spiel) weiterläuft, aber jetzt beim Aufruf von run() friert das Gui!? Und der Konstruktor des Threads ruft nur super auf und setzt sich zwei Variablen.

    Ich hoffe ich habe einigermaßen verständlich meine Probleme darlegen können und freue mich wie immer auf jeden Hinweis, den ich verfolgen kann.

    Nicholas

  • du darfst auch nicht run() aufrufen sondern musst start() nehmen!

    die methode, die du implementieren musst heißt zwar run, wenn du sie aber direkt aufrufst wird kein neuer thread gestartet sondern die methode genau wie jede andere aufgerufen. das bedeutet, dass das ganze so lange blockiert bis die methode mit ihrer arbeit fertig ist.
    beim aufruf der start-methode hingegen wird der neue thread gestartet und blockiert nicht.

    so wie du's oben machst gehts zwar, standard bei solchen sachen ist eher, dass man einen neuen thread startet der die einkommenden requests verarbeitet und der empfänger-thread wieder auf den nächsten request wartet...
    aber das ist wohl nur eine stilfrage.

    "All through my life I've had this strange unaccountable feeling that something was going on in the world, something big, even sinister, and no one would tell me what it was."
    "No," said the old man, "that's just perfectly normal paranoia. Everyone in the Universe has that."

    😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐😒😓😔😖😘😚😜😞😠😡😢😣😥😨😩😪😫😭😰😱😲😳😵😶😷

  • Schon wieder ein Problem.

    Wenn ich jetzt das Programm starte über den Editor. Dann kommt im EditorLogFeld ununterbrochen:
    java.lang.IllegalMonitorStateException
    Ich glaub das hat etwas damit zu tun, dass ich dem Thread auch mein Server Objekt als Referenz mitgebe. Aber wie kann ich das jetzt beheben? Das Problem ist, dass ich eine zentrale Klasse hab, auf die alle Threads zugreifen können sollen (synchronized natürlich).

  • Zitat von Javadoc

    Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.

    das heißt, dass du wahrscheinlich entweder wait oder notify von einem objekt aufrufst, auf das nicht synchronisiert wird.
    ansonsten kann ich ohne weitere informationen nicht mehr sagen...

    "All through my life I've had this strange unaccountable feeling that something was going on in the world, something big, even sinister, and no one would tell me what it was."
    "No," said the old man, "that's just perfectly normal paranoia. Everyone in the Universe has that."

    😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐😒😓😔😖😘😚😜😞😠😡😢😣😥😨😩😪😫😭😰😱😲😳😵😶😷

  • Es stimmt, ich rufe die Methode wait() auf. Habe nämlich noch einen Neben-Thread, der alle 2 Sekunden prüft (wait(2000)), ob auf dem server schon zwei Clients in der ReadyToPlay Liste drin stehen. Ist dies der Fall, dann startet der Neben-Thread eine Methode des Servers und das Spiel beginnt.

  • wenns nur ums warten geht solltest du besser Thread.sleep(int) verwenden.
    wait() sollte man verwenden, wenn man dann irgendwo die notify-methode des objektes aufrufen möchte.

    "All through my life I've had this strange unaccountable feeling that something was going on in the world, something big, even sinister, and no one would tell me what it was."
    "No," said the old man, "that's just perfectly normal paranoia. Everyone in the Universe has that."

    😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐😒😓😔😖😘😚😜😞😠😡😢😣😥😨😩😪😫😭😰😱😲😳😵😶😷

  • Hallo
    Ich habe für meinen Server als Trennzeichen zwischen Befehl für das Protokoll und Inhalt folgendes Zeichen gewählt:
    String.valueOf((char)55555)
    Wenn ich mir dieses Zeichen in meinem ServerGUI anzeigen lasse, bekomme ich, da es sich nicht um ein der Schriftart bekanntes Zeichen handelt, ein Kästen heraus. So soll es sein. Gibt mein ClientGUI allerdings das Zeichen aus, so steht da ein "?". So soll es nicht sein. Was ist schief gegangen beim Übertragen?
    Ich benutze PrintWriter und BufferedReader mit den Methoden println und readLine

    Danke im Voraus

  • du verwendest da ja ein ziemlich unübliches trennzeichen... glaube nicht, dass das nach der übertragung auch wirklich so ankommen wird!
    prinzipiell gibt es da glaube ich 2 möglichkeiten:
    1 - du verwendest ein ascii-zeichen mit einem wert < 256, das wird sicher korrekt übertragen
    2 - du werwendes java.io.DataInputStream.readUTF() und java.io.DataOutputStream.writeUTF(String) für ein- und ausgaben --> sollte funktionieren, keine garantie!

    "All through my life I've had this strange unaccountable feeling that something was going on in the world, something big, even sinister, and no one would tell me what it was."
    "No," said the old man, "that's just perfectly normal paranoia. Everyone in the Universe has that."

    &#128513;&#128514;&#128515;&#128516;&#128517;&#128518;&#128519;&#128520;&#128521;&#128522;&#128523;&#128524;&#128525;&#128526;&#128527;&#128528;&#128530;&#128531;&#128532;&#128534;&#128536;&#128538;&#128540;&#128542;&#128544;&#128545;&#128546;&#128547;&#128549;&#128552;&#128553;&#128554;&#128555;&#128557;&#128560;&#128561;&#128562;&#128563;&#128565;&#128566;&#128567;

  • (Das bezieht sich jetzt auf dein 55555-Zeichen):

    Wenn du so ein Zeichen auf der Konsole ausgibst, dann muss es irgendwie in eine 8-bit-Darstellung gebracht werden. Typischerweise in latin-1, aber auch utf-8 ist heutzutage nicht unüblich. Im Fall von latin-1 kann das Zeichen natürlich nicht dargestellt werden, daher das ?. Falls es utf-8 ist, könnte trotzdem ein ? rauskommen, wenn die Konsole zwar utf-8 versteht, aber nicht weiß, wie sie das Zeichen darstellen soll. GUIs haben damit normalerweise kein Problem, weil sie intern soundso mit Unicode-Strings arbeiten und daher das Umkodieren entfällt.

  • habs jetzt mal ausprobiert, mit readUTF und writeUTF kommts wie erwartet richtig an.
    interessanterweise wird das zeichen nicht nur als ? dargestellt, sonder kommt nach der übertragung wirklich als ? (ascii 63) an. wahrscheinlich wird es schon vor der übertragung umgewandelt...

    "All through my life I've had this strange unaccountable feeling that something was going on in the world, something big, even sinister, and no one would tell me what it was."
    "No," said the old man, "that's just perfectly normal paranoia. Everyone in the Universe has that."

    &#128513;&#128514;&#128515;&#128516;&#128517;&#128518;&#128519;&#128520;&#128521;&#128522;&#128523;&#128524;&#128525;&#128526;&#128527;&#128528;&#128530;&#128531;&#128532;&#128534;&#128536;&#128538;&#128540;&#128542;&#128544;&#128545;&#128546;&#128547;&#128549;&#128552;&#128553;&#128554;&#128555;&#128557;&#128560;&#128561;&#128562;&#128563;&#128565;&#128566;&#128567;

  • Ich wollte keinen neuen Thread anfangen, weil es ja immer noch das selbe Projekt ist.

    Ich lasse die Spielfläche immer Zeichnen mit java.awt.Graphics. Sobald ich jedoch ein Fenster über das Spielfeld ziehe ist das gemalte wieder verschwunden. Wie kann ich das verhindern? Muss ich da eine repaint Methode oder so neu schreiben?


    Danke wie immer im Voraus

    EDIT: Hab es jetzt mal mit der Methode Paint versucht.
    Diese überlagert in meinem abgeleiteten Panel, sodass mein Spielfeld immer mit den Aktuellen Daten gezeichnet wird.
    Allerdings fehlt da in der Regel die Ecke die das überlappende Fenster zuletzt überdeckt hat.
    Außerdem ist die Spielfläche wieder weg, wenn das Fenster mal kurz in den Hintergrund kommt, bzw minimiert wird.

    2 Mal editiert, zuletzt von Nicholas1991 (19. Dezember 2008 um 22:59)

Jetzt mitmachen!

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