# Einlesen von Servernachrichten von TCP-Client



## jono (11. Aug 2021)

Hallo,

unzwar habe ich einen Client programmiert mit Reader und Writer. Mir geht es jetzt erstmal nur abstrakt darum, wie ich das schaffe. Also nachdem Reader im Code soll etwas kommen, was konkrete Nachrichten spezifiziert. Es gibt mehrere Servernachrichten, die geschickt werden können und nun muss ich diese voneinander differenzieren, was ich grundsätzlich erstmal mit einem split-Array machen würde und dann die verschiedenen Spalten definieren. Aber kann mir evtl. jemand weiterhelfen? Mir fällt es gerade schwer da konkret im Code zu werden...

Und daneben muss ich es auch so implementieren, sodass wenn eine bestimmte Nachricht den Tcp-Client reicht, dass dann ein für die Nachricht vorgesehener Command ausgeführt wird, um dann die Programmlogik dementsprechend zu verändern


----------



## VfL_Freak (11. Aug 2021)

Bitte was??

Bitte beschreib' Dein Problem nochmal neu und ausfürhllicher und so, dass man es auch verstehen kann!
Dafür wäre sicherlich der vorhandene Code (CodeTags!!) extremst hilfreich


----------



## jono (11. Aug 2021)

```
Thread reader = new Thread() {
                @Override
                public void run() {
                    try (InputStreamReader in = new InputStreamReader(socket.getInputStream(), cs); 
                    // z.B.   "PSCO" PlayerId Score <- PlayerId und Score sind Integer
                            OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream(), cs)) {
                        int c = in.read();
                        while (!socket.isClosed() && c >= 0) {
                            out.write(c);
                            out.flush();
                            c = in.read();
                        }
                        System.out.println("Fini2.");
                        // read System.in and send data to socket's output stream
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                };
            };
```
s.o. genannter Kommentar. Hier möchte ich vordefinierte Nachrichten einlesen, was ja durch einen Reader passiert. Nun soll die beispielsweise obige Nachricht eintreffen von Server Richtung Client. Was muss ich machen, um dann z.B. über ein PlayerScoreCommand die Punkte von einem Spieler zu verändern. Also Einlesen, die Felder definieren, z.B.  int score = array[1]. -> Das Array: String[] array = ...split("\t);
Was kommt vor split? Wie kann ich das alles in Einklang bringen?


----------



## Barista (11. Aug 2021)

jono hat gesagt.:


> Es gibt mehrere Servernachrichten, die geschickt werden können und nun muss ich diese voneinander differenzieren





jono hat gesagt.:


> Und daneben muss ich es auch so implementieren, sodass wenn eine bestimmte Nachricht den Tcp-Client reicht, dass dann ein für die Nachricht vorgesehener Command ausgeführt wird, um dann die Programmlogik dementsprechend zu verändern


Du musst ein Protokoll definieren und dann auf Client-Seite und Server-Seite implementieren (Encoder und Parser).

Zum Codieren des Command kannst Du ein Byte verwenden, falls 256 Werte ausreichen.

Jedem Command-Byte kannst Du weitere Parameter zuordnen, die nach dem Command-Byte übertragen werden.

Einfach ist es, wenn die Parameter immer eine konstante Länge haben.

Wenn die Parameter keine konstante Länge haben, benötigst vor dem variable langen Daten-Stück eine Längen-Information oder am Ende eine Ende-Information, die natürlich nicht in der Information verwendet werden dürfen.


----------



## jono (11. Aug 2021)

Barista hat gesagt.:


> Du musst ein Protokoll definieren und dann auf Client-Seite und Server-Seite implementieren (


Server ist schon vorgegeben, kann nur auf Client Seite verändern.


Barista hat gesagt.:


> Zum Codieren des Command kannst Du ein Byte verwenden, falls 256 Werte ausreichen


Verstehe die Aussage nicht wirklich. Ein Command muss ich ja nur kreieren, z.B. wenn die eben genannte Nachricht eintritt, dann muss eine Instanz vom PlayerScoreCommand erzeugt werden, worüber dann die Methode aufgerufen wird.



Barista hat gesagt.:


> Jedem Command-Byte kannst Du weitere Parameter zuordnen, die nach dem Command-Byte übertragen werden.
> 
> Einfach ist es, wenn die Parameter immer eine konstante Länge haben.
> 
> Wenn die Parameter keine konstante Länge haben, benötigst vor dem variable langen Daten-Stück eine Längen-Information oder am Ende eine Ende-Information, die natürlich nicht in der Information verwendet werden dürfen.


Auch hier kann ich dir nicht folgen, kannst du bitte versuchen das nochmal leichter zu formulieren? Wäre echt gut


----------



## Jw456 (11. Aug 2021)

> Server ist schon vorgegeben, kann nur auf Client Seite verändern.


Da wäre es interessant wie so ei e Nachricht vom Server ausschaut. Zeige mal ein Beispiel. 

Du empfängt im Moment nur ein Zeichen. Und geht in eine Schleife. 
Wo du das empfange Zeichen an den Server zurück schickst warum das?


----------



## jono (11. Aug 2021)

Jw456 hat gesagt.:


> Da wäre es interessant wie so ei e Nachricht vom Server ausschaut. Zeige mal ein Beispiel.


"PSCO" 12345 42.


Jw456 hat gesagt.:


> Du empfängt im Moment nur ein Zeichen. Und geht in eine Schleife.
> Wo du das empfange Zeichen an den Server zurück schickst warum das?


Ich empfange nur ein Zeichen, weil der InputStreamReader nur immer eins bekommt. Wollte das eben eigentlich schon fragen, wie ich das anders machen kann, sodass direkt eine ganze line eingelesen werden kann, irgendwas mit einem LineNumberReader?

Und das empfangene Zeichen züruckzuschicken macht überhaupt keinen Sinn. Das ist noch von einer anderen Anwendung, muss aber gelöscht werden, ja.


----------



## Jw456 (11. Aug 2021)

Ist am Ende ein enter Zeichen CR
Dann benutze einen bufferedreader


----------



## jono (11. Aug 2021)

Warum benutzt man genau dann einen Buffered Reader? Und woher soll ich wissen ob am Ende ein enter Zeichen ist?


----------



## Jw456 (11. Aug 2021)

Weil


jono hat gesagt.:


> Warum benutzt man genau dann einen Buffered Reader? Und woher soll ich wissen ob am Ende ein enter Zeichen ist?


Weil du da gleich eine Zeile mit readLine lesen kannst.


----------



## Barista (11. Aug 2021)

jono hat gesagt.:


> Warum benutzt man genau dann einen Buffered Reader?


BufferedReader unterstützt zeilenweises Lesen.



			java BufferedReader zeile lesen - Google Suche


----------



## jono (11. Aug 2021)

Barista hat gesagt.:


> BufferedReader unterstützt zeilenweises Lesen.


Hätte dazu auch was gelesen, dort habe ich nur etwas über charactertechnisches Einlesen erfahren.
Okay, über den kann ich dann auch die Zeilen splitten oder? Also es sollte doch so funktionieren, dass ich jetzt anstelle des Kommentars eben im Code-Tag ein String-Array initialisieren kann:

```
String[] test = buf.split(...);
```
Wobei buf die Instanzvariable vom BufferedReader darstellen soll.


----------



## Barista (11. Aug 2021)

jono hat gesagt.:


> Okay, über den kann ich dann auch die Zeilen splitten oder?


Nein, aber die Zeile (String) kannst Du dann mit anderen Mitteln splitten.


----------



## jono (11. Aug 2021)

Wie Splitte ich dann? Ein String-Array sollte doch sinnvoll sein. Aber wiee initialisiere ich es richtig und wie recherchiere ich am besten , wie ich die eingelesenen Zeilen von BufferedReader richtig Splitte


----------



## jono (11. Aug 2021)

https://www.java-forum.org/thema/zeilen-in-array-einlesen-und-splitten.172508/
		


So sollte es doch funktionieren..
Die Zeilen möchte ich ja nicht ausgeben. Also ohne System.out.println
Würde dann stattdessen dort hinschreiben

```
String psco = teilen[1].trim ();
int id = teilen[1].trim();
int score = teilen[2].trim();
```
Oder wie könnte ich das besser schreiben. Bin mir nicht sicher ob das so wirklich Sinn macht.


----------



## jono (11. Aug 2021)

Und ich möchte ja jetzt für 8 Servernachrichten die Array Felder neu definieren und dann noch hinzufügen dass wenn das erste Array Feld zb psco ist dann soll Instanz von der dazugehörigen command Klasse erzeugt werden und daraufhin die Methode dieser.
Kannst du mir evtl eine abstrakte Struktur oder so vorschlagen, da hängt es gerade bei mir...


----------



## Barista (11. Aug 2021)

jono hat gesagt.:


> Wie Splitte ich dann?


Wenn Du hier Hilfe benötigst, musst Du auch eine sinnvolle Frage stellen.
Sind die Token innerhalb einer Zeile immer mit Leerzeichen getrennt?
Kann das Leerzeichen zwischen Apostrophen auftauchen ("PS CO")?


jono hat gesagt.:


> Ein String-Array sollte doch sinnvoll sein.


Das wäre das Ergebnis des Splittens, nicht die Methode des Splittens.


----------



## kneitzel (11. Aug 2021)

Mein Tipp ist: Spiel doch mit den Methoden, die Du nutzen willst oder die interessant aussehen, etwas rum. Nur so lernst Du, was Du damit alles machen kannst und wie die Methoden sich verhalten. Das ist existenzielles Wissen, wenn Du so Programme schreiben willst.


----------

