# Server/Client-Kommunikation



## ExceptionOfExpectation (14. Apr 2022)

Hallo, ich praktiziere gerade mein Wissen mit Server-Applikationen, dafür möchte ich mit Threads arbeiten. An meiner simplen Beispiel-Applikation versuche ich das Wissen zu vertiefen.

zwei Java-Klassen Server & Client
beide erben von Thread
Server Klasse erstellt eine Datei mit dem Inhalt (falls nicht vorhanden)
durch die synchronisierte generateOutputStream()-Methode wird eine While-Schleife gestartet (solange die einen Inhalt aufweist)
dieser Inhalt wird zum Client geschickt als ein Output
gleich danach in der Schleife wird der Server zum warten geschickt
ab hier soll Client Klasse starten mit der synchronisierten printContext()-Methode
hier wirkt eine andere While-Schleife in einer Abwechslung mit der ersten Schleife aus der Server Klasse
der Inhalt soll auf der Konsole ausgegeben werden
  In der Theorie ist alles soweit schlüssig, nur wenn ich die Java-Dateien einzeln starte, wird nur die Verbindung zwischen den Server und Client bestätigt, der Informationsaustausch zwischen zwei Threads bleibt aber auf der Strecke.
  Ich nehme an, dass der Wartezustand bei der Monitoring von Client-Thread nicht aufgehoben wurde. Kann mir eine helfen?


----------



## ExceptionOfExpectation (14. Apr 2022)

```
package com.server;

import java.net.Socket;
import java.net.ServerSocket;
import java.net.UnknownHostException;
import java.io.*;
import java.util.Scanner;

public class Server extends Thread{

    ServerSocket server;
    Socket client;

    String fileName = "myDoc.txt";
    File file;
    public static int port = 5555;

    InputStreamReader isr;
    BufferedReader serverIn;

    OutputStreamWriter osw;
    PrintWriter serverOut;

    Scanner date;

    public void run(){
        try{
            this.server = new ServerSocket(port);
            //this.client = server.accept();
            System.out.println("Server 5555 wurde erstellt!");
            getExistFile(fileName);
            date = new Scanner(file);
        }catch(IOException io){ System.out.println("IOEXception in run()-Methode"); }
        try{
            this.client = server.accept();
            System.out.println("Verbindung zu Socket " + client.getRemoteSocketAddress() + " aufgenommen");
        }catch(UnknownHostException uhe){ System.out.println("Die Verbindung zum Client fehlgeschlagen!"); }
        catch(IOException ioe){ System.out.println("Streamstörung von Server!"); }
        generateOutputStream();
    }


    public void getExistFile(String fileName){
        try{    file = new File(fileName);
            if(file.createNewFile()){
                System.out.println("Was created!");
                serverOut = new PrintWriter(new FileOutputStream(fileName));
                serverOut.println("Das ist ein langes Text\n" +
                    "Er wird langsam übertragen\n" +
                    "Zeile nach der Zeile\n" +
                    "Vom Server zum Client\n" +
                    "Wird OutputStream von Server\n" +
                    "Zum InputStream von Client\n" +
                    "Das ist der Trick!");
                serverOut.flush();
            }else{    System.out.println("allready exists");    }
        }catch(IOException io){
             System.out.println("Dateiprüfung fehlgeschlagen!");
        }
    }


    public synchronized void generateOutputStream(){
        try{
            while(date.hasNextLine()){
                serverOut = new PrintWriter(client.getOutputStream(), true);
                serverOut.println(date.nextLine());
                serverOut.flush();
                wait();
            }
            closeAll();
        }catch(IOException ioe){
            System.out.println("Es könnte keine Information von Server geholt werden!");  }
        catch(InterruptedException ie){ System.out.println("ServerThread koennte nicht zum warten geschickt werden!"); }
    }
    
    public void closeAll(){
        try{
            serverOut.close();
            server.close();
        }catch(IOException ioe){
            System.out.println("Servernkonnte nicht geschlossen werden!");
        }
            
    }

    public static void main(String [] args){
        Server server = new Server();
        server.start();
    }


    
}
```


```
package com.client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;


public class Client extends Thread{


    private Socket client;

    public static int port = 5555;
    
    BufferedReader serverIn;
    
    private String text;

    public void run(){
        try{
            this.client = new Socket("localhost", port);
            this.serverIn = new BufferedReader(new InputStreamReader(client.getInputStream()));
        }catch(IOException ioe){ System.out.println("Der Inhaltübernahme von Server zum Client hat nicht erfolgt!");
        }
        printContext();
    }
    
    public synchronized void printContext(){
        try{
            while(serverIn.readLine() != null){
                text = serverIn.readLine();
                System.out.println(text);
                wait();
            }
        close();
        }catch(IOException ioe){ System.out.println("Ausgabe gescheitert! "); }
        catch(InterruptedException ie) {System.out.println("ClientThread koennte nicht zum warten geschickt werden!");}
    }

    public void close(){
        try{
            serverIn.close();
            client.close();
        }catch(IOException ioe){ System.out.println("Der Client konnte nicht geschlossen werden!"); }
    }

    public static void main(String [] args){
        Client client = new Client();
        client.start();
    }
}
```


----------



## KonradN (14. Apr 2022)

Warum rufst Du im Client wait() auf? Damit blockierst Du doch den Client:


> Causes the current thread to wait until it is awakened, typically by being _notified_ or _interrupted_.








						Object (Java SE 17 & JDK 17)
					

declaration: module: java.base, package: java.lang, class: Object



					docs.oracle.com
				




Edit: Im Server natürlich ebenso. Das wait macht da ja auch keinen Sinn.


----------



## ExceptionOfExpectation (15. Apr 2022)

KonradN hat gesagt.:


> Warum rufst Du im Client wait() auf? Damit blockierst Du doch den Client:
> 
> 
> 
> ...


  Mir ist vor kurzem eingefallen, dass ich vergessen habe notify() vor wait() einzufügen:
Während ich den Client in den Wartezustand schicke, aktiviere ich mit notify(), den anderen Thread von Server und so wollte ich, dass sie abwechselnd die Schleifen durchlaufen, so zu sagen durch die synchronisierten Methoden zwei Schleifen miteinander verketten.
    Mein Algorithmus entspricht nicht dieser Logik, soweit ich gelernt habe, überträgt die notify()-Methode die Monitoring an den nächsten Thread und aktiviert ihn aus dem Wartezustand.


----------



## KonradN (15. Apr 2022)

Das notify und wait ist für die Threadsteuerung eines Prozesses und nicht Prozessübergreifend. Und schon gar nicht um auf entfernte Rechner einzuwirken.

Noch einmal die Frsge: Wieso machst du das? Was willst du damit erreichen?

Edit: Evtl. die Frage umformulieren: Wieso glaubst du, würdest du so eine Synchronisation brauchen?


----------



## ExceptionOfExpectation (15. Apr 2022)

KonradN hat gesagt.:


> Das notify und wait ist für die Threadsteuerung eines Prozesses und nicht Prozessübergreifend. Und schon gar nicht um auf entfernte Rechner einzuwirken.
> 
> Noch einmal die Frsge: Wieso machst du das? Was willst du damit erreichen?
> 
> Edit: Evtl. die Frage umformulieren: Wieso glaubst du, würdest du so eine Synchronisation brauchen?


So habe ich es aus dem Buch gelernt, das einzig was von mir kommt ist die Zusammenarbeit mit den Schleifen. Ich will zwei Schleifen synchron ablaufen lassen, statt alles in einem Puffer zu sammeln und dann einen synchronisierten Ablauf zu simulieren.


----------



## Jw456 (15. Apr 2022)

Hallo ich glaube du hast das Grundprinzip nicht richtig verstanden.

Server und Cient sind zwei getränte Programme die eigentlich auch auf unterschiedlichen Rechnern laufen. Die laugen dann Parallel zur gleichen Zeit eigenständig.

Wenn du es auf dem Gleichen Rechner testen willst sind es auch hier zwei Programme die das Betriebssystem dann verwaltet und gleichzeitig ausführt.

Das warten wie du es dir vorstellts macht hier der Stream selber, darum musst du dich nicht kümmern.



PS was das mit dem synchronized soll erschließt sich mir nicht, welcher Thread soll den da dazwischen funken es gibt ja nur einen.


----------



## ExceptionOfExpectation (15. Apr 2022)

Jw456 hat gesagt.:


> Hallo ich glaube du hast das Grundprinzip nicht richtig verstanden.
> 
> Server und Cient sind zwei getränte Programme die eigentlich auch auf unterschiedlichen Rechnern laufen. Die laugen dann Parallel zur gleichen Zeit eigenständig.
> 
> ...


Ach, jetzt verstehe ich vorauf Ihr hinaus wollt. Es geht um eine Kopplungsstrategie zwischen unterschiedlichen Modulen. Ich habe das Potenzial in Thread-Technologie gesehen und jetzt möchte ich wissen wie weit man mit abgesicherten Methoden kommt.


----------



## Jw456 (15. Apr 2022)

Eines sollte erst mal klar sein es gibt keinen Kopplung zwischen Server und Client.
Die ist nur auf Netzwerk Seite nichts mit deinem Code.





> Während ich den Client in den Wartezustand schicke, aktiviere ich mit notify(), den anderen Thread von Server und so wollte ich, dass sie abwechselnd die Schleifen durchlaufen, so zu sagen durch die synchronisierten Methoden zwei Schleifen miteinander verketten.


Das eine Programm kennt das andere gar nicht kann auch nicht auf irgendwelche daten des anderen zugreifen. Mir kommt es so vor als ob du das so in etwa denkst.
Betrachte immer nur ein Programm.


Im Server zb gibt es nur einen Thread. Die Methode generateOutputStream() wir nur einmal aufgerufen und das noch aus dem selben Thread heraus ich sehe keinen Grund zur Synchronisation.
Da müsstest du schon mehre Thread in deinen Server haben die Daten liefern.


----------



## ExceptionOfExpectation (15. Apr 2022)

Jw456 hat gesagt.:


> Eines sollte erst mal klar sein es gibt keinen Kopplung zwischen Server und Cient.
> Die ist nur auf Netzwerk Seite nichts mit deinem Code.
> 
> 
> ...


Danke, jetzt ist mir klar, dass ich meine Client-Seite noch um einiges erweitern muss, um an das gewünschte Effekt zu kommen. 
 War total auf die Möglichkeiten von Threads fixiert, ich habe der Tatsache, dass es zwei getrennte Programme sind, wenig Bedeutung gegeben.


----------



## ExceptionOfExpectation (28. Apr 2022)

Hallo nochmal, ich habe jetzt noch ein anderes Problem bekommen, ausschließlich nur mit diesem Beispiel:
 Kann mir jemand erklären wie es sein kann, dass nach der erfolgreichen Verbindung zum Server der client.getInputStream() leer ausfällt?


----------



## KonradN (28. Apr 2022)

ExceptionOfExpectation hat gesagt.:


> nach der erfolgreichen Verbindung zum Server der client.getInputStream() leer ausfällt


Was genau machst Du und was willst Du genau sagen?
getInputStream liefert den InputStream von dem Socket. Das sollte eigentlich nie null sein (Falls Du mit leer sowas meinst).

Damit Du aus diesem InputStream etwas lesen kannst, muss das natürlich erst einmal vom Server gesendet worden sein. Und wenn Du mit einem BufferedReader und readLine arbeitest, muss in dem, was da empfangen wurde, auch ein Zeilenumbruch sein.

Wenn Du uns mehr Details gibst (Source und auch genaues, beobachtetes Verhalten bei genauer Beschreibung der Ausführung), dann können wir auch deutlich mehr dazu sagen. Aber so fehlt irgendwie die Grundlage, auf der man Aussagen treffen könnte.


----------



## Jw456 (28. Apr 2022)

Ohne deinen jetzigen code kann man keine sinnvolle hilfe geben.


----------



## fhoffmann (28. Apr 2022)

```
while(serverIn.readLine() != null){
                text = serverIn.readLine();
```
Das ist keine gute Idee: in der while-Bedingung liest du den Text (und ignorierst ihn). In der nächsten Zeile versuchst du erneut, Text zu lesen (den es im Zweifelsfall nicht gibt).


----------



## ExceptionOfExpectation (28. Apr 2022)

fhoffmann hat gesagt.:


> ```
> while(serverIn.readLine() != null){
> text = serverIn.readLine();
> ```
> Das ist keine gute Idee: in der while-Bedingung liest du den Text (und ignorierst ihn). In der nächsten Zeile versuchst du erneut, Text zu lesen (den es im Zweifelsfall nicht gibt).


Habe das korrigiert (Danke)


KonradN hat gesagt.:


> Was genau machst Du und was willst Du genau sagen?
> getInputStream liefert den InputStream von dem Socket. Das sollte eigentlich nie null sein (Falls Du mit leer sowas meinst).
> 
> Damit Du aus diesem InputStream etwas lesen kannst, muss das natürlich erst einmal vom Server gesendet worden sein. Und wenn Du mit einem BufferedReader und readLine arbeitest, muss in dem, was da empfangen wurde, auch ein Zeilenumbruch sein.
> ...


Ich will nur diesen Beispiel zur Ende bringen. Ich habe verstanden, dass ich zwei Applikationen nicht zu einem Prozess umgewandelt werden können. Hier geht es mir nur um zu verstehen, der Server-Output beinhaltet schon alles, trotzdem wird auf der Client-Seite Exception geworfen und da ist kein Inhalt drin.


----------



## Jw456 (28. Apr 2022)

Klar das dein serverIn leer ist. Du hast ja zu dem Zeitpunkt auch noch nichts vom Client aus an der Server geschickt noch gar keinen request gemacht.
Einen output stream der etwas an den Server schickt sehe ich in dem Client nicht.
Es wurde vom Cient aus keine Verbindung zum Server aufgebaut hergestellt.
Damit meine ich aus der Klasse Client heraus.

Ist immer noch das alte Thema.


----------



## fhoffmann (28. Apr 2022)

ExceptionOfExpectation hat gesagt.:


> trotzdem wird auf der Client-Seite Exception geworfen


Was wird denn für eine Exception geworfen?


----------



## KonradN (28. Apr 2022)

ExceptionOfExpectation hat gesagt.:


> trotzdem wird auf der Client-Seite Exception geworfen


Kannst Du uns auch noch die genauen Exception Details geben? Auf den ersten Blick sieht es relativ gut aus. Der Server sendet nur die Textdatei und der Client sollte eigentlich diese empfangen und ausgeben.


----------



## Jw456 (28. Apr 2022)

KonradN hat gesagt.:


> Kannst Du uns auch noch die genauen Exception Details geben? Auf den ersten Blick sieht es relativ gut aus. Der Server sendet nur die Textdatei und der Client sollte eigentlich diese empfangen und ausgeben.


Ich sehe keine output stream im Client der eine Verbindung aufbaut. Mit hilfe des socket.


----------



## KonradN (28. Apr 2022)

Jw456 hat gesagt.:


> Ich sehe keine output stream im Client der eine Verbindung aufbaut.


Die Verbindung baut der Socket auf - unabhängig davon, ob Du nun einen OutputStream vom Socket nutzt oder nicht. Er nutzt einfach keinen OutputStream, da er nichts zum Server schickt. Beim Server nutzt er auch nicht den InputStream um irgendwas zu lesen, daher ist das so erst einmal in Ordnung.

@ExceptionOfExpectation 
Was aber evtl. auch noch fehlt ist die Ausgabe der Exception. Also im catch noch sowas wie ioe.printStackTrace() machen ... Und in der Ausgabe evtl. noch ioe.getMessage() mit ausgeben. Das sind die Informationen, die wir anfragen und die Du evtl. selbst nicht hast (und uns daher auch bisher nicht gegeben hast).


----------



## KonradN (28. Apr 2022)

Was beim Server noch auffällt:
- In getExistFile erstellst Du die Datei - da schließt Du den PrintWriter nicht. Sowas bitte immer per try-with-resources machen. Dann braucht man auch kein flush (beim Schließen ist das mit inbegriffen). Das ändert dann den Code zu sowas:

```
public void getExistFile(String fileName) {
        file = new File(fileName);
        if (file.createNewFile()) {
            System.out.println("Was created!");
            try (serverOut =new PrintWriter(new FileOutputStream(fileName))){
                serverOut.println("Das ist ein langes Text\n" + "Er wird langsam übertragen\n" + "Zeile nach der Zeile\n" + "Vom Server zum Client\n" + "Wird OutputStream von Server\n" + "Zum InputStream von Client\n" + "Das ist der Trick!");
            } catch(IOException io) {
                System.out.println("Dateiprüfung fehlgeschlagen: " + io.getMessage());
                io.printStackTrace();
            }
        } else {
            System.out.println("allready exists");
        }
    }
```
(Enthält ggf. Tippfehler.)

Und das macht kein Sinn:
`System.out.println(serverOut.toString());`
Da kommt dann vermutlich nur etwas raus wie java.io.PrintWriter@<HashCode>


----------



## ExceptionOfExpectation (28. Apr 2022)

Jw456 hat gesagt.:


> Klar das dein serverIn leer ist. Du hast ja zu dem Zeitpunkt auch noch nichts vom Client aus an der Server geschickt noch gar keinen request gemacht.
> Einen output stream der etwas an den Server schickt sehe ich in dem Client nicht.
> Es wurde vom Cient aus keine Verbindung zum Server aufgebaut hergestellt.
> Damit meine ich aus der Klasse Client heraus.
> ...


Was genau meinst du wurde beim Client nicht gestartet? Die Run-Methode wurde gestartet, schaue genauer hin. 


KonradN hat gesagt.:


> Kannst Du uns auch noch die genauen Exception Details geben? Auf den ersten Blick sieht es relativ gut aus. Der Server sendet nur die Textdatei und der Client sollte eigentlich diese empfangen und ausgeben.


IOException:

```
public synchronized void printContext(){
        try{    String text ="";
            while((text = serverIn.readLine()) != null){
                
                System.out.print(text);

                
            }
        close();
        }catch(IOException ioe){ System.out.println("Ausgabe gescheitert! "); }
        
    }
```


----------



## LimDul (28. Apr 2022)

Du solltest den Stacktrace der IO-Exception ausgeben (oder mindestens die Message). So verschluckst du die eigentliche Fehlermeldung.


----------



## ExceptionOfExpectation (28. Apr 2022)

KonradN hat gesagt.:


> Was beim Server noch auffällt:
> - In getExistFile erstellst Du die Datei - da schließt Du den PrintWriter nicht. Sowas bitte immer per try-with-resources machen. Dann braucht man auch kein flush (beim Schließen ist das mit inbegriffen). Das ändert dann den Code zu sowas:
> 
> ```
> ...


In der Korrektur habe ich nicht ganz verstanden (Zeile 5) Fett hervorgehoben. Meintest du statt das Schlüsselwort try das Schlüsselwort if? Es war doch die ganze Zeit mit try-catch-Block umhüllt


----------



## KonradN (28. Apr 2022)

Das try dort ist ein sogenanntes try with resources. Die Resource dort implementiert AutoClosable und dabei wird sicher gestellt, dass beim Verlassen des try Blocks auf der Resource close() aufgerufen wird (Etwas, das bei dir komplett fehlte). Der Link bringt Dich zur Dokumentation von Oracle.

Es geht also nicht um das try catch sondern um das Schließen der Resource.


----------



## Jw456 (28. Apr 2022)

ich habe den code mal getestet 
ich erhalte diese Meldung

```
Dateiprüfung fehlgeschlagen: Connection reset
java.net.SocketException: Connection reset
    at java.base/java.net.SocketInputStream.read(SocketInputStream.java:186)
    at java.base/java.net.SocketInputStream.read(SocketInputStream.java:140)
    at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
    at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.base/java.io.InputStreamReader.read(InputStreamReader.java:181)
    at java.base/java.io.BufferedReader.fill(BufferedReader.java:161)
    at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326)
    at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392)
    at Client.printContext(Client.java:45)
    at Client.<init>(Client.java:26)
    at Client.main(Client.java:70)
```


----------



## KonradN (28. Apr 2022)

Ich habe das jetzt auch einmal probiert und bei mir lief es erfolgreich durch. Was ich bei mir gemacht habe war aber die Anpassung zu Ende umgesetzt. Die Methode war so nicht übersetzbar, da das file.createFile auch eine IOException werfen kann und das try with resources muss natürlich eine lokale Variable erstellen. Damit sieht der Server, den ich getestet habe, so aus:

```
import java.net.Socket;
import java.net.ServerSocket;
import java.net.UnknownHostException;
import java.io.*;
import java.util.Scanner;

public class Server extends Thread {

    public static int port = 5555;

    ServerSocket server;

    Socket client;

    String fileName = "myDoc.txt";

    File file;

    InputStreamReader isr;

    BufferedReader serverIn;

    OutputStreamWriter osw;

    PrintWriter serverOut;

    Scanner date;

    public static void main(String[] args) {
        Server server = new Server();
        server.start();
    }

    public void run() {
        try {
            this.server = new ServerSocket(port);

            System.out.println("Server 5555 wurde erstellt!");
            getExistFile(fileName);
            date = new Scanner(new FileReader(fileName));
        } catch (IOException io) {
            System.out.println("IOEXception in run()-Methode");
        }

        try {
            this.client = server.accept();
            System.out.println("Verbindung zu Socket " + client.getRemoteSocketAddress() + " aufgenommen");
        } catch (UnknownHostException uhe) {
            System.out.println("Die Verbindung zum Client fehlgeschlagen!");
        } catch (IOException ioe) {
            System.out.println("Streamstörung von Server!");
        }
        generateOutputStream();
    }

    public void getExistFile(String fileName) {
        try {
            file = new File(fileName);
            if (file.createNewFile()) {
                System.out.println("Was created!");
                try (PrintWriter serverOut = new PrintWriter(new FileOutputStream(fileName))) {
                    serverOut.println("Das ist ein langes Text\n" + "Er wird langsam übertragen\n" + "Zeile nach der Zeile\n" + "Vom Server zum Client\n" + "Wird OutputStream von Server\n" + "Zum InputStream von Client\n" + "Das ist der Trick!");
                }
            } else {
                System.out.println("allready exists");
            }
        } catch (IOException io) {
            System.out.println("Dateiprüfung fehlgeschlagen: " + io.getMessage());
            io.printStackTrace();
        }
    }

    public synchronized void generateOutputStream() {
        try {

            serverOut = new PrintWriter(client.getOutputStream());
            String text = "";
            while ((text = date.nextLine()) != null) {
                System.out.print(text + "\n");
                serverOut.write(text);
                System.out.println(serverOut.toString());
                serverOut.flush();

            }

            closeAll();
        } catch (IOException ioe) {
            System.out.println("Es könnte keine Information von Server geholt werden!");
        }
    }

    public void closeAll() {
        try {
            serverOut.close();
            server.close();
        } catch (IOException ioe) {
            System.out.println("Servernkonnte nicht geschlossen werden!");
        }

    }

}
```

Der Client so:

```
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

public class Client extends Thread {

    public static int port = 5555;

    BufferedReader serverIn;

    private Socket client;

    private String text;

    public static void main(String[] args) {
        Client client = new Client();
        client.start();
    }

    public void run() {
        try {
            this.client = new Socket("localhost", port);
            this.serverIn = new BufferedReader(new InputStreamReader(client.getInputStream()));
        } catch (IOException ioe) {
            System.out.println("Der Inhaltübernahme von Server zum Client hat nicht erfolgt!");
        }
        printContext();
    }

    public synchronized void printContext() {
        try {
            String text = "";
            while ((text = serverIn.readLine()) != null) {
                System.out.print(text);
            }
            close();
        } catch (IOException ioe) {
            System.out.println("Ausgabe gescheitert! ");
            System.out.println("Exception: " + ioe.getMessage());
            ioe.printStackTrace();
        }
    }

    public void close() {
        try {
            serverIn.close();
            client.close();
        } catch (IOException ioe) {
            System.out.println("Der Client konnte nicht geschlossen werden!");
        }
    }
}
```

Und beim Start lief es durch:

```
konrad@TermServ Downloads % java Server
Server 5555 wurde erstellt!
Was created!
Verbindung zu Socket /127.0.0.1:61808 aufgenommen
Das ist ein langes Text
java.io.PrintWriter@57795495
Er wird langsam übertragen
java.io.PrintWriter@57795495
Zeile nach der Zeile
java.io.PrintWriter@57795495
Vom Server zum Client
java.io.PrintWriter@57795495
Wird OutputStream von Server
java.io.PrintWriter@57795495
Zum InputStream von Client
java.io.PrintWriter@57795495
Das ist der Trick!
java.io.PrintWriter@57795495
Exception in thread "Thread-0" java.util.NoSuchElementException: No line found
        at java.base/java.util.Scanner.nextLine(Scanner.java:1651)
        at Server.generateOutputStream(Server.java:78)
        at Server.run(Server.java:53)
konrad@TermServ Downloads %
```
(Die Exception kommt hier am Ende, weil der Code natürlich schlicht falsch ist. Scanner liefert nicht null, wenn nichts mehr da ist! Da muss halt in der while Schleife ein "hasNext" oder so geprüft werden um dann in der Schleife ein nextLine aufzurufen.)

Und dann noch die Ausgabe des Clients bei mir:

```
konrad@TermServ Downloads % java Client
Das ist ein langes TextEr wird langsam übertragenZeile nach der ZeileVom Server zum ClientWird OutputStream von ServerZum InputStream von ClientDas ist der Trick!%                           
konrad@TermServ Downloads %
```


----------



## ExceptionOfExpectation (28. Apr 2022)

KonradN hat gesagt.:


> Ich habe das jetzt auch einmal probiert und bei mir lief es erfolgreich durch. Was ich bei mir gemacht habe war aber die Anpassung zu Ende umgesetzt. Die Methode war so nicht übersetzbar, da das file.createFile auch eine IOException werfen kann und das try with resources muss natürlich eine lokale Variable erstellen. Damit sieht der Server, den ich getestet habe, so aus:
> 
> ```
> import java.net.Socket;
> ...


Ich danke dir, ich schaue es mir später an und teste es, nach den Kopfschmerzen


----------



## Jw456 (28. Apr 2022)

Konrad zur Info die Fehlermeldung von mir war von Client nicht vom Server

beim server bekomme ich die gleiche wie du


----------



## KonradN (28. Apr 2022)

Jw456 hat gesagt.:


> Konrad zur Info die Fehlermeldung von mir war von Client nicht vom Server


Das war mir klar, nur eben habe ich diese bei mir nicht. Ich bin mir im Augenblick auch nicht sicher, was diesen ausgelöst haben könnte. Der ganze Code ist extrem unsauber, so dass die Fehlererkennung auch recht schwer ist.

Das sieht etwas danach aus, dass der Stream geschlossen wird, während eine Zeile gelesen wird. Aber da ist mir die Konstellation gerade nicht klar, wie da das Verhalten des Sockets sein muss. Wenn der Server den Socket schließt, dann sollte der Client die bisher gesendeten Daten noch problemlos lesen können.

Bekommst Du mit meinem Code auch diese Exception? Also mal probieren: Nur mein Code und wenn da der Fehler nicht kommt dann die Kombination eins von mir und eins der Code, bei dem Du die Exception hattest.


----------



## Jw456 (28. Apr 2022)

Nachdem ich das mit dem Scanner geändert habe geht es bei mir auch.
Ich hatte einfach zwischendurch einen festen string geschickt und ging auch.

Mit deinem Code ohne Änderung habe ich auch den Fehler.


----------



## Jw456 (28. Apr 2022)

Der Fehler kommt im client in der while schon beim ersten Lesen.


----------



## ExceptionOfExpectation (1. Mai 2022)

Ic


KonradN hat gesagt.:


> Das war mir klar, nur eben habe ich diese bei mir nicht. Ich bin mir im Augenblick auch nicht sicher, was diesen ausgelöst haben könnte. Der ganze Code ist extrem unsauber, so dass die Fehlererkennung auch recht schwer ist.
> 
> Das sieht etwas danach aus, dass der Stream geschlossen wird, während eine Zeile gelesen wird. Aber da ist mir die Konstellation gerade nicht klar, wie da das Verhalten des Sockets sein muss. Wenn der Server den Socket schließt, dann sollte der Client die bisher gesendeten Daten noch problemlos lesen können.
> 
> Bekommst Du mit meinem Code auch diese Exception? Also mal probieren: Nur mein Code und wenn da der Fehler nicht kommt dann die Kombination eins von mir und eins der Code, bei dem Du die Exception hattest.


ich habe so eben getestet, zwar hatte ich eine Vermutung, dass es an Scanner-Objekt liegen könnte, aber nicht auf diese Weise. 
DIe Kontrol-Systemoutput-Befehle habe ich nachhinein eingebaut, da ich in das Output schauen wollte, mehr ist da nichts. 
 Alles funktioniert jetzt richtig, vielen Dank


----------

