Hallo,
ich habe ein Problem. Ich muss ein Programm schreiben, welches die eingegeben Daten vom Client beim Server in einem Textdokument speichert. Es geht hierbei um eine einfache Abfrage. Ich habe die Verbindung hinbekommen, die Abfragen etc. läuft alles wunderbar.
Mein einziger Fehler ist, dass ich es nicht hinbekomme, das wenn ich den Server beende und neustarte und versuche die Daten aus der vorherigen Session zu holen, es nicht funktioniert. Das heißt die Daten werden nicht persistent gespeichert oder können nicht gelesen werden. Ich weiß nicht wo der Fehler liegt.
Ich poste hier meine 4 Klassen, alles ist schön ausdokumentiert. Ich hoffe ihr könnt mir helfen.
Die Klasse Server
Die Klasse Client
Die Klasse SDS
Die Klasse QueryInit
ich habe ein Problem. Ich muss ein Programm schreiben, welches die eingegeben Daten vom Client beim Server in einem Textdokument speichert. Es geht hierbei um eine einfache Abfrage. Ich habe die Verbindung hinbekommen, die Abfragen etc. läuft alles wunderbar.
Mein einziger Fehler ist, dass ich es nicht hinbekomme, das wenn ich den Server beende und neustarte und versuche die Daten aus der vorherigen Session zu holen, es nicht funktioniert. Das heißt die Daten werden nicht persistent gespeichert oder können nicht gelesen werden. Ich weiß nicht wo der Fehler liegt.
Ich poste hier meine 4 Klassen, alles ist schön ausdokumentiert. Ich hoffe ihr könnt mir helfen.
Die Klasse Server
Java:
package Aufgabe_4_1;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server {
private final static int PORT = 7824;
private static ServerSocket serverSocket;
private static Socket socket;
private static ExecutorService pool;
static QueryInit qi = new QueryInit();
public static void main(String args[]) {
try {
//eine bound connection mit einen port
serverSocket = new ServerSocket(PORT);
//generiert eine fixe anzahl an thread auf ein unbound connection
pool = Executors.newFixedThreadPool(10);
System.out.println("Threadpool generated, Server waiting for clients...");
while (true) {
socket = serverSocket.accept();
//aufgrund des startens der Thread muss ich runnable implementieren
Runnable task = new RunTask(socket);
pool.execute(task);
}
} catch (IllegalArgumentException | SecurityException | IOException e) {
e.printStackTrace();
//explziter shutdown
pool.shutdown();
}
}
/**
* Statische innere Klasse
* RunTask welche Runnable implementiert, sie erstellt Instanzvariablen
* Dem Konstruktor initialisiert
*/
static private class RunTask implements Runnable {
private Socket myConnection;
private ObjectOutputStream outStream;
private ObjectInputStream inStream;
private String message = null;
//konstruktor der ein socket erwartet
public RunTask(Socket connection) {
this.myConnection = connection;
try {
outStream = new ObjectOutputStream(myConnection.getOutputStream());
inStream = new ObjectInputStream(myConnection.getInputStream());
} catch (IOException e) {
e.printStackTrace();
System.out.println("Warning: Streams are invalid");
}
}
/**
* Die Run Methode wird als Serverteil komplett ausgeführt und übernimmt die Anfragen vom Client und bearbeitet diese jeweils
* Alles läuft in einen try block ab um eventuelle Fehler fangen zu können
*/
public void run() {
try {
/**
* Die Abfrage erfolgt hier zum Client. Der Server bekommt dasselbe zu sehen wie der Client
*/
System.out.println("Connected to: " + socket.getInetAddress().getHostName());
message = "Do you brush your teeth before you go sleep? " + "\nYou can answer with yes, no and other";
//schreibt und sendet den String im UTF8 Format
outStream.writeUTF(message);
outStream.flush();
System.out.println("Server: " + message);
/**
* Hier wird die Antwort des Clients eingelesen und versucht zu speichern
* Schleife wird abgebrochen, wenn eine Antwort einkommt
*/
while (true) {
//antwort einlesen / auf anfrage warten
message = inStream.readUTF();
System.out.println(myConnection.getInetAddress().getHostName() + ": " + message);
//wenn eine antwort ausgewählt wurde, soll diese im textdokument gepeichert werden
if(message.equals("yes") || message.equals("no") || message.equals("other")){
//Todo: Dieses objekt muss vielleicht statisch sein
//QueryInit qi = new QueryInit();
qi.save(message);
break;
}else{
//wenn was falsches gesendet wird, dann soll wrong ausgegeben werden
message = "Wrong Input! Please answer with yes, no or other";
outStream.writeUTF(message);
outStream.flush();
System.out.println("Server: " + message);
}
}
/**
* Wenn alles richtig war, dann soll er fragen ob der Client den aktuellen Status sehen will
*/
message = "Thank you for be a part of answering \nDo you wanna know your actual status? \nyes or no?";
outStream.writeUTF(message);
outStream.flush();
System.out.println("Server: " + myConnection.getInetAddress().getHostName() + ": " + message);
/**
* Hier antwortet der Client, bei yes bekommt er seinen aktuellen Status, bei no wird die Verbindung geschlossen
*/
while (true){
//antwort einlesen, anfrage warten
message = inStream.readUTF();
System.out.println(myConnection.getInetAddress().getHostName() + ": " + message);
//falls antwort ja, dann zeig mir die aktuellen ergebnisse
if(message.equals("yes")){
//QueryInit qi2 = new QueryInit();
message = qi.showSDS();
outStream.writeUTF(message);
outStream.flush();
//falls nein, dann weiter
}else if(message.equals("no")){
message = "finish";
outStream.writeUTF(message);
outStream.flush();
break;
}else{
message = "wrong input";
outStream.writeUTF(message);
outStream.flush();
System.out.println("Server an " + myConnection.getInetAddress() + ": " + message);
}
}
/**
* Hier wird die Verbindung geschlossen, wenn der client bei der abfrage ob er den aktuellen Status
* einsehen will, no geantwortet hat
*/
//Streams schließen, Verbindung schließen
myConnection.shutdownOutput();
myConnection.shutdownInput();
myConnection.close();
System.out.println("Connection " + myConnection.getInetAddress().getHostName() + " closed");
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
Die Klasse Client
Code:
package Aufgabe_4_1;
import java.io.*;
import java.net.Socket;
import java.net.SocketException;
public class Client {
public static void main(String[] args) throws IOException {
/**
* verbindungsaufbau zu diesen socket
*/
String serverName = "localhost";
int portNr = 7824;
System.out.println("Open Socket to " + serverName + " up " + portNr);
Socket socket = new Socket(serverName, portNr);
/**
* sowohl instanziierung als auch ablauf des clients im try block
*/
try {
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
String message = null;
System.out.println("Connected to: " + socket.getInetAddress().getHostName());
/**
* einlesen und abarbeiten, while-schleife läuft solange bis client oder server abbricht
*/
while (true) {
try {
//liest einen utf 8 format String
message = in.readUTF();
} catch (IOException e) {
e.printStackTrace();
break;
}
/**
* wenn user irgendwas falsches eingetippt hat
*/
if (message.equals("wrong")) {
System.out.println(socket.getInetAddress().getHostName() + " : Please choose another an answer");
}
if (message.equals("finish")) {
break;
} else {
System.out.println(socket.getInetAddress().getHostName() + " : " + message);
}
/**
hier überprüfe ich die verbindungseinstellungen
*/
if (socket.isConnected() == false) {
System.out.println("finish");
break;
}
if (socket.isInputShutdown()) {
System.out.println("finish");
break;
}
if (socket.isOutputShutdown()) {
System.out.println("finish");
break;
}
if (socket.isBound() == false) {
System.out.println("finish");
break;
}
/**
*liest die eingegebene message ein für die abfrage vom server ob ich meine daten einsehen will
*/
message = keyboard.readLine();
try {
out.writeUTF(message);
out.flush();
} catch (IOException e) {
e.printStackTrace();
break;
}
}
System.out.println("Connection closed");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Die Klasse SDS
Code:
package Aufgabe_4_1;
import java.io.Serializable;
/**
* SDS = Stammdatensatz
*/
public class SDS implements Serializable {
public int yes = 0;
public int no = 0;
public int other = 0;
}
Die Klasse QueryInit
Code:
package Aufgabe_4_1;
import java.io.*;
public class QueryInit implements Serializable {
SDS sds = new SDS();
String filename = "Umfrage-Ergebnisse.txt";
/**
* Diese Methode verarbeitet die Antwort vom Client und schreibt diese in das Textdokument
* @param answer : String
*/
public synchronized void save(String answer) {
System.out.println("Start Initialisation");
try {
//file in die daten gespeichert werden können
FileOutputStream fos = new FileOutputStream(filename);
//speichere objekte in dieser file
ObjectOutputStream oos = new ObjectOutputStream(fos);
//liefer mir die datensätze
this.sds = getSDS();
//zähl mir die stimmen hoch
if (answer.equals("yes")) {
this.sds.yes++;
} else if (answer.equals("no")) {
this.sds.no++;
} else if (answer.equals("other")) {
this.sds.other++;
}
//schreibe mir das den stammdatensatz als objekt in meine file
oos.writeObject(this.sds);
oos.flush();
//Schliess mir den stream
oos.close();
fos.close();
System.out.println("Stream closed, Data saved");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Diese Methode holt mir den aktuellen Stand aus meiner File heraus.
* @return sds : SDS
*/
private SDS getSDS() {
try {
//offne mir den stream auf mein file
FileInputStream fos1 = new FileInputStream(filename);
//lese objekte in diesem file aus
ObjectInputStream oos1 = new ObjectInputStream(fos1);
this.sds = (SDS) oos1.readObject();
//neue schreibweise, verknüpfung von vielen exception aufeinmal
} catch (NullPointerException | ClassNotFoundException | IOException e) {
System.out.println("Nothing to read");
}
//setz mir alles auf 0, wenn objekt nicht beschrieben
if(this.sds == null){
this.sds.yes = 0;
this.sds.no = 0;
this.sds.other = 0;
}
return this.sds;
}
/**
* Diese Methode verschönert mir die Ausgabe
* @return message : String
*/
public String showSDS (){
this.sds = getSDS();
String message = "Actual results: \nyes: " + this.sds.yes + " \nno: " + this.sds.no + " \nother: " + this.sds.other;
return message;
}
}