Server/Client-Kommunikation

ExceptionOfExpectation

Aktives Mitglied
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?
 

Anhänge

  • Server.java
    2,5 KB · Aufrufe: 1
  • Client.java
    1,2 KB · Aufrufe: 0
Zuletzt bearbeitet:

ExceptionOfExpectation

Aktives Mitglied
Java:
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();
    }


    
}

Java:
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();
    }
}
 

ExceptionOfExpectation

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


Edit: Im Server natürlich ebenso. Das wait macht da ja auch keinen Sinn.
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

Super-Moderator
Mitarbeiter
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

Aktives Mitglied
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

Top Contributor
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.
 
Zuletzt bearbeitet:

ExceptionOfExpectation

Aktives Mitglied
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 verwalte und gleichzeitig ausführt.

Das warten wie du es dir vorstellts macht hier der Stream selber darum musst du dich nicht kümmern.
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

Top Contributor
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.
 
Zuletzt bearbeitet:

ExceptionOfExpectation

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




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.
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

Aktives Mitglied
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

Super-Moderator
Mitarbeiter
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.
 

fhoffmann

Top Contributor
Java:
            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

Aktives Mitglied
Java:
            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)
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.
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.
 

Anhänge

  • Server.java
    2,5 KB · Aufrufe: 0
  • Client.java
    1,1 KB · Aufrufe: 0

Jw456

Top Contributor
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.
 
Zuletzt bearbeitet:

KonradN

Super-Moderator
Mitarbeiter
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

Super-Moderator
Mitarbeiter
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:
Code:
    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

Aktives Mitglied
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.
Was genau meinst du wurde beim Client nicht gestartet? Die Run-Methode wurde gestartet, schaue genauer hin.
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:
Java:
    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

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

ExceptionOfExpectation

Aktives Mitglied
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:
Code:
    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>
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
 
Zuletzt bearbeitet:

KonradN

Super-Moderator
Mitarbeiter
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

Top Contributor
ich habe den code mal getestet
ich erhalte diese Meldung
Java:
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

Super-Moderator
Mitarbeiter
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:
Java:
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:
Java:
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:
Code:
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:
Code:
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

Aktives Mitglied
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:
Java:
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:
Java:
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:
Code:
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:
Code:
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 %
Ich danke dir, ich schaue es mir später an und teste es, nach den Kopfschmerzen
 

KonradN

Super-Moderator
Mitarbeiter
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

Top Contributor
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.
 

ExceptionOfExpectation

Aktives Mitglied
Ic
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
 

Eichelhäer

Bekanntes Mitglied
Der Post ist zwar vom letzten Jahr, aber ich habe das gleiche Problem. Ich habe einen Chat Server laufen, der mehrere Clients aufnehmen kann. Das erreiche ich dadurch, dass ich die server.accept() methode in einer while Schleife aufrufe. Ich kann zwar beliebig viele Clients aufnehmen, allerdings, sobald ein Client die Verbindung trennt kommt dieser Connection reset - Fehler mit einer Socket exception und nur dann, also egal ob nur ein Client gerade angemeldet ist oder mehrere. Auf anderen Foren habe ich zwar auch etwas dazu gefunden allerdings kaum konkrete Lösungsvorschläge. In der documentation steht:

"The socket uses the system-default socket implementation and a virtual thread is accepting a connection. In that case, interrupting the virtual thread will cause it to wakeup and close the socket. This method will then throw SocketException with the interrupt status set."

Allerdings weiß ich immernoch nicht wie ich diese Exception abfangen kann.

Vielleich weiß da jemand mittlerweile Rat.

Grüße Eichelhäer
 

LimDul

Top Contributor
Dafür müsste man den Code sehen. In der simpelsten Varianten spawnt man für jeden Client einen Thread - und da kann man in dem Thread die Exception catchen und den Thread beenden.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
I Client/Server Kommunikation bei einem Spiel Netzwerkprogrammierung 4
brainless Client Server Kommunikation verschlüsseln Netzwerkprogrammierung 13
T Socket Server/Client Kommunikation Netzwerkprogrammierung 8
P MIME-TYPE Erklaerung, Kommunikation zwischen Client und Server Netzwerkprogrammierung 3
J Sichere Kommunikation bei Server Client Netzwerkprogrammierung 3
M allgemeine Frage über Server-Client-Kommunikation Netzwerkprogrammierung 5
L Ratschlag zur Umsetzung einer client-server-Kommunikation Netzwerkprogrammierung 6
R Server zu Client Kommunikation Netzwerkprogrammierung 11
V Socket UDP Server/Client Kommunikation sehr langsam Netzwerkprogrammierung 2
F Socket Server/Client Kommunikation Netzwerkprogrammierung 4
X Problem mit Server-Client-Kommunikation Netzwerkprogrammierung 14
D Server-Client (Web) Kommunikation Netzwerkprogrammierung 9
E Client-Server-Kommunikation Netzwerkprogrammierung 13
C HTTP Studienarbeit Kommunikation via HTTP mit POST zwischen Server und Client Netzwerkprogrammierung 7
G Problem mit Client-Server Kommunikation Netzwerkprogrammierung 4
G unvollständige Daten: Http Client-Server-Kommunikation Netzwerkprogrammierung 2
J client/server kommunikation Netzwerkprogrammierung 3
M Client-Kommunikation ohne Server Netzwerkprogrammierung 7
S Kommunikation Fortran <-> Java auf Client-Server-Archi Netzwerkprogrammierung 2
G JINI über RMI // Client-Server Kommunikation Netzwerkprogrammierung 4
I Performanteste Kommunikationsmethode zwischen Client u. Server Netzwerkprogrammierung 4
L Socket Automatische Zuweisung von Server und Client Rolle Netzwerkprogrammierung 12
M Server-Client-System für Browsergame Netzwerkprogrammierung 5
Yonnig Threads mit Client/Server und GUI (laufend bis button-click) Netzwerkprogrammierung 9
J Client-Server und SOAP Netzwerkprogrammierung 23
L30nS RMI Aufruf einer Client-Methode von einem RMI-Server Netzwerkprogrammierung 3
T String von Client zu Server kommt nicht an Netzwerkprogrammierung 92
D WebSocket Server mit HTML Client und Java Server Netzwerkprogrammierung 5
D Server - Client Informationsaustausch, Möglichkeiten Netzwerkprogrammierung 3
H Socket Chat entwickeln mit Java Server Client Netzwerkprogrammierung 4
X Kann ich einen Client/Server verbindung hinkriegen die mir alle paar Sekunden die aktuellen Daten per Realtime zuschickt ? Netzwerkprogrammierung 9
D Slf4j - Logging - Client-Server Architektur Netzwerkprogrammierung 3
J client server mit nur einem PC Netzwerkprogrammierung 33
M Socket Nachricht von TCP-Client an Server schicken Netzwerkprogrammierung 12
M Socket Verbindung Matlab(Server) Java(Client) Netzwerkprogrammierung 1
R Socket FATAL EXCEPTION MAIN bei Socket based client/server app Netzwerkprogrammierung 2
G Server-Client IO Problem Netzwerkprogrammierung 6
I Socket Das erste Server-Client Programm Netzwerkprogrammierung 16
M Socket Server antwortet dem Client nicht Netzwerkprogrammierung 6
E Objekte versenden, Client-Server Netzwerkprogrammierung 25
C Mini Client-Server-Anwendung funktioniert nicht Netzwerkprogrammierung 8
P Server als Client nutzen Netzwerkprogrammierung 8
D Socket Run Args Client/Server Socket Netzwerkprogrammierung 1
Cromewell Socket Multithreaded Server und Client Netzwerkprogrammierung 1
Y Client/Server/DB communication Netzwerkprogrammierung 3
JavaWolf165 Socket mit .writeUtf etwas vom Client zum Server schicken Netzwerkprogrammierung 13
P RMI Client Server Programm über Internet Netzwerkprogrammierung 2
gamebreiti Socket Server / Client Anwendung Manipulation von Objekten durch Server Netzwerkprogrammierung 9
F Server Client Anwendung mit UDP Netzwerkprogrammierung 2
A RMI Wo treten Exceptions bei RMI Aufrufen auf? Auf Client oder auf Server? Netzwerkprogrammierung 3
A ByteBuffer - Client/Server Netzwerkprogrammierung 9
K C# Server - Android Client Netzwerkprogrammierung 0
T Frage zu Client-Server Applikation Netzwerkprogrammierung 2
H Socket Client/Server Socket Programmieren Netzwerkprogrammierung 1
M Theoretische Frage zu Server - Client Netzwerkprogrammierung 2
P HTTP Server / Client Netzwerkprogrammierung 1
E Thematik Client server Netzwerkprogrammierung 2
D Client/Server per Crossover Lan Kabel Netzwerkprogrammierung 1
S Client Server Connection Netzwerkprogrammierung 4
V erste Client - Server Anwendung, paar Fragen wie Socketverbindung checken usw. Netzwerkprogrammierung 4
S Sichere Server/Client Architektur Netzwerkprogrammierung 1
D Chat Server/mehre Client Netzwerkprogrammierung 9
I Server+Client Netzwerkprogrammierung 3
N Client am Server abmelden Netzwerkprogrammierung 0
F Server/Client Probleme Netzwerkprogrammierung 3
U Socket Instant Messanger (Server Linux, Client Windows) Netzwerkprogrammierung 1
Athena Grundsatzfragen zu Client-Server-Architektur / Matchmaking Netzwerkprogrammierung 1
A Problem beim Senden von Client zu Server Netzwerkprogrammierung 10
F Client Server DB Netzwerkprogrammierung 0
A Verständnisfrage Multi-Threaded Client/Server Netzwerkprogrammierung 5
F Tipps zum Thema Server/Client vie SOAP Netzwerkprogrammierung 0
F Socket Java - Server/Client simple Netzwerkprogrammierung 1
R Zeitliche Syncronisation Server - Client Netzwerkprogrammierung 0
S Server-Client: Image senden Netzwerkprogrammierung 2
C Multithreading Client / Server erklärt Netzwerkprogrammierung 11
P server - client verbindung (anfänger) Netzwerkprogrammierung 8
J Client Server - Serialisierung Netzwerkprogrammierung 8
Luk10 Server / Client: Clients speichern! Netzwerkprogrammierung 6
K Client => Server Netzwerkprogrammierung 2
A ? Home-Network, Server/Client-Einrichtung Netzwerkprogrammierung 4
S Socket Server: ConnectionError vom Client erkennen Netzwerkprogrammierung 31
A Java Server - IOS Client Applikation Netzwerkprogrammierung 20
M RMI RMI Probleme zwischen Client und Server Netzwerkprogrammierung 5
J Erster Server-Client läuft auf lokalem Rechner problemlos. Zwei Rechner über das Internet nicht Netzwerkprogrammierung 8
N Client-Server-Datenbank Netzwerkprogrammierung 13
Kjubert Synchronisieren von Objekten über Client/Server - bester Weg? Netzwerkprogrammierung 7
B Client/Server Connection Problem Netzwerkprogrammierung 2
S Server Client Daten hin und herschicken Netzwerkprogrammierung 2
D TCP Verbindung (Java Client und Visual Basic Server) Netzwerkprogrammierung 12
S Socket Applet Client bekommt keine GLOBALE Verbindung zum Server Netzwerkprogrammierung 25
T Server und Client verbinden nicht Netzwerkprogrammierung 6
D Server Client Verbindung - Unexpected End of File - Invalid HTTP Response Netzwerkprogrammierung 4
das-mo Client/Server sendet nicht Netzwerkprogrammierung 7
Z Socket Server/Client vernünftiger Verbindungsabbruch Netzwerkprogrammierung 4
G Bild über Socket schicken - Client/Server Netzwerkprogrammierung 10
F TCP Server/Client Netzwerkprogrammierung 14
M Problem Client - Server Sockets: .ready() wird nie true! Netzwerkprogrammierung 6
Ollek Socket Sucher passende Server/Client Lösung für meine Anwendung Netzwerkprogrammierung 2
N eine klasse mit server & client Netzwerkprogrammierung 5
D RMI Gui auf client updaten basierend auf den Property Änderung des Models auf dem Server ohne polling Netzwerkprogrammierung 12

Ähnliche Java Themen

Neue Themen


Oben