Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
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?
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.
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?
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.
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.
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.
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.
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.
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?
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.
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).
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).
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.
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.
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.
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.
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).
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>
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.
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.
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
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.
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)
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 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 %
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.
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
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.
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.