import java.io.*;
import java.net.Socket;
/**
* @author zengin
* Die Klasse ControlerThread dient dazu, die Klasse ViewThread und die Klasse ModelThread
* also die beiden Threads via Pipe miteinander zu verbinden und anschliessend zu starten.
*/
public class ControlerThread
{
/**
* @param args
* @throws ClassNotFoundException
* @throws IOException
* Die main-Methode dient dazu, die beiden Threads (ModelThread und ViewThread) über
* die Pipe zum Laufen zu bringen.
* Innerhalb der main-Methode werden als erstes PipedReader und PipedWriter erzeugt.
* Anschliessend werden PipedReader und PipedWriter miteinander verbunden.
* Im nächsten Schritt wird ein neues ViewThread t1 und ein neues ModelThread t2 erzeugt,
* der ViewThread t1 bekommt als Parameter pr2 und pw1 und der ModelThread t2
* bekommt als Parameterübergabe pr1 und pw2. Dann werden die neu erzeugten Threads
* anschliessend asynchron gestartet.
* pw1 also die Pipe1 schreibt vom ViewThread zum ModelThread
* und pw2 also Pipe2 schreibt vom ModelThread zum ViewThread.
*/
@SuppressWarnings("resource")
public static void main(String[] args) throws IOException
{
String requestToServer;
String ipadresse = Input.readString("Geben Sie bitte die IP-Adresse zum Verbinden ein: ");
Socket clientSocket = new Socket(ipadresse, 45678);
System.out.println("Verbindung zum Server mit der Adresse "
+ clientSocket.getInetAddress() + " wurde hergestellt.");
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
clientSocket.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(
System.in));
PipedReader pr1 = new PipedReader();
PipedWriter pw1 = new PipedWriter();
PipedReader pr2 = new PipedReader();
PipedWriter pw2 = new PipedWriter();
PipedReader prControllerVonModel = new PipedReader();
PipedReader prControllerVonView = new PipedReader();
PipedWriter pwControllerZuModel = new PipedWriter();
PipedWriter pwControllerZuView = new PipedWriter();
pwControllerZuModel.connect(pr1);
pwControllerZuView.connect(pr2);
pw2.connect(prControllerVonModel);
pw1.connect(prControllerVonView);
ViewThread t1 = new ViewThread(pr2, pw1);
ModelThread t2 = new ModelThread(pr1, pw2);
t1.start(); //asynchroner Start
t2.start(); // asynchroner Start
int a;
while (true)
{
try
{
a = prControllerVonView.read();
requestToServer = "" + a;
bw.write(requestToServer);
bw.newLine();
bw.flush();
pwControllerZuModel.write(a);
prControllerVonModel.read();
pwControllerZuView.write(0);
}
catch (Exception e)
{
e.printStackTrace();
System.exit(1);
}
}
}
}
import java.io.*;
import java.util.*;
/**
* @author zengin
*/
public class ModelThread extends Thread
{
File csvdatei = new File("adreli.csv");
public static ArrayList<Person> personen = new ArrayList<Person>();
private PipedReader reader;
private PipedWriter writer;
/**
* Konstruktor mit 2 Parametern.
* @param reader
* @param writer
*/
public ModelThread(PipedReader reader, PipedWriter writer)
{
super("ModelThread");
this.reader = reader;
this.writer = writer;
}
/**
* Die Klasse ModelThread wird über die sogenannte Pipe mithilfe dieser Methode zum Laufen gebracht.
* Falls die Eingaben aus der ViewThread-Klasse gelesen wurden, kann somit jetzt die jeweilige Methode
* ausgeführt werden. Der Thread der Benutzerseite wird gestartet.
* int a = reader.read(); liest von der Pipe, welcher Casefall eingegeben wurde.
* Mithilfe der Methode-write wird an das Hauptmenü ein Signal übergeben.
* Der Programmlauf wird in diesem Fall an die ViewThread-Klasse übergeben.
* Sobald die Eingabe aus der Klasse ViewThread gelesen ist, wird die jeweilige
* Methode der Klasse ModelThread ausgeführt.
*/
public void run()
{
while (true)
{
try
{
int a = reader.read(); // es liest von der Pipe, welcher casefall eingegeben worden ist.
switch (a)
{
case 1: // eine neue Person aufnehmen
personeneingabe();
break;
case 2: // Records auflisten
personenausgabe();
break;
case 3: // Records in eine Datei sichern
sichern(personen);
break;
case 4: // Datei löschen
fileLoeschen();
break;
case 5: // das Programm verlassen
programmbeenden();
break;
default: // Falsche Zahl eingegeben
System.out
.println("Sie haben keine gültige Zahl eingegeben, bitte geben Sie eine Zahl von 1 - 5 ein!");
}
writer.write(a);
}
catch (IOException io)
{
System.out.println("Es ist ein Fehler im ModelThread aufgetreten:" + "\n" + io.getMessage());
}
}
}
/**
* 2. while-Schleife fragt ab, ob Eingaben korrekt sind. Wenn die Eingaben korrekt sind,
* werden die Personenobjekte mit dem Befehl personen.add(p) in die ArrayList personen eingetragen.
*/
public void eingabenkorrektheit()
{
boolean beenden = false;
while (!beenden)
{
System.out.println();
System.out.println("Geben Sie bitte Ihre Daten ein: ");
System.out.println();
Person p = new Person();
p.readPerson();
while (!beenden)
{
String antwort =Input.readString(
"Sind Ihre Eingaben korrekt?\n(J/j = Ja, N/n = Nein)");
if (antwort.equals("J") || antwort.equals("j"))
{
beenden = true;
}
else if (antwort.equals("N") || antwort.equals("n"))
{
p.readPerson();
beenden = false;
}
else
{
System.out.println(
"Ihre Eingabe ist nicht gültig, bitte nochmals versuchen!\n");
beenden = false;
}
}
personen.add(p);
String antwort = Input.readString(
"Möchten Sie noch weitere Personendaten aufnehmen?\n(J/j = Ja, N/n = Nein)",
"[jJnN]",
"Ihre Eingabe war leider fehlerhaft, bitte versuchen Sie es erneut!");
if (antwort.equals("J") || antwort.equals("j"))
{
beenden = false;
}
else if (antwort.equals("N") || antwort.equals("n"))
{
beenden = true;
}
else
{
System.out.println("Sie haben eine ungültige Eingabe betätigt, bitte erneut versuchen!\n");
beenden = false;
}
}
}
/**
* diese Methode ruft die Methode eingabenkorrektheit() auf, um abfragen zu können,
* ob die eingegebenen Personeninformationen korrekt sind oder nicht.
* Und ob der Benutzer noch weitere Personendaten aufnehmen möchte.
*
*/
public void personeneingabe()
{
eingabenkorrektheit();
}
/**
* Die Personeninformationen, die im ArrayList personen gespeichert wurden, werden mithilfe
* der Methode personenausgabe() einzeln, satzweise und nacheinander aufgelistet auf dem
* Bildschirm angezeigt.
*/
public void personenausgabe()
{
for (int i = 0; i<personen.size(); i++)
{
System.out.println(i+1+"."+"Satz");
System.out.println();
System.out.println(personen.get(i).toString());
Input.readString("Betätigen Sie bitte die <RETURN> - Taste um weiterzukommen\n");
}
}
/**
* @param personen (ArrayList)
* Auslagerung der Informationen von Personobjekten in die
* Datei adreli.csv. FileWriter dient dazu, dass die
* entsprechenden Personendaten char-artig in die Datei adreli.csv
* geschrieben werden. Anhand der for-Schleife werden die
* einzelnen Attribute mittels BufferedWriter in die Datei
* geschrieben, jedoch getrennt und nicht hintereinander.
*/
public void sichern(ArrayList<Person> personen)
{
try {
BufferedWriter bw = new BufferedWriter(new FileWriter("adreli.csv"));
for (Person p : personen)
{
bw.write(p.name + ";");
bw.write(p.vorname + ";");
bw.write(p.anrede + ";");
bw.write(p.strasse + ";");
bw.write(p.plz + ";");
bw.write(p.ort + ";");
bw.write(p.telefon + ";");
bw.write(p.fax + ";");
bw.write(p.bemerkung + ";" + "\n");
}
bw.close();
System.out.println("Ihre Daten wurden in die Datei adreli.csv gespeichert!");
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
}
/**
* loescht Datei "adreli.csv" zusammen mit gespeicherten
* Personendaten von der Festplatte. Im try-Block wird versucht, die neu
* angelegte Datei adreli.csv von der Festplatte zu löschen. Falls es gelöscht
* wurde, soll auf dem Bildschrirm ausgegeben werden, dass die Datei adrelicsv
* erfolgreich gelöscht wurde. Im anderen Fall, falls es die Datei auf der Festplatte
* nicht gibt, soll eine Fehlermeldung ausgegeben werden, dass die Datei
* adreli.csv auf der Festplatte nicht vorhanden ist.
*/
public static void fileLoeschen()
{
try {
File datei = new File("adreli.csv");
if(datei.exists())
{
datei.delete();
System.out.println("Die Datei " + "adreli.csv" + " wurde erfolgreich gelöscht.\n");
}
else
{
System.out
.println("Die Datei adreli.csv ist auf der Festplatte leider nicht vorhanden.\n");
}
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
/**
* Mithilfe der Methode programmbeenden hat der Benutzer die Möglichkeit
* das Programm erfolgreich zu verlassen. System.exit(0); dient in dieser
* Methode dazu, damit der Benutzer das Programm vorzeitig beenden kann.
*/
public static void programmbeenden()
{
System.exit(0);
}
}
import java.io.Serializable;
/**
* Mithilfe der Klasse "Person" werden Daten über Personen erfasst
* @author zengin
*/
public class Person implements Serializable
{
public String name;
public String vorname;
public String anrede;
public String strasse;
public String plz;
public String ort;
public String telefon;
public String fax;
public String bemerkung;
static final long serialVersionUID = 0L;
/**
* überprüft den eingegebenen Namen mithilfe des angegebenen regulären Ausdrucks
* auf syntaktische Korrektheit
*/
public void read_in_Name()
{
System.out.println("(z.B. Musterfrau)");
name = Input.readString("Name: ","([A-ZÖÜ][a-zöü]+)",
"\nGeben Sie Ihren Namen bitte nach dem Muster des angezeigten Beispiels ein!");
}
/**
* überprüft den eingegebenen Vorname mithilfe des angegebenen regulären Ausdrucks
* auf syntaktische Korrektheit
*/
private void read_in_Vorname()
{
System.out.println("(z.B. Maria)");
System.out.println("(z.B. Ana-Marie)");
vorname = Input.readString("Vorname: ",
"([A-ZÖÜ][a-zöü]+)|([A-ZÖÜ][a-zöü]+[-][A-ZÖÜ][a-zöü]+)",
"\nGeben Sie Ihren Vornamen bitte nach dem Muster des angezeigten Beispiels ein! ");
}
/**
* überprüft die eingegebene Anrede mithilfe des angegebenen regulären Ausdrucks
* auf syntaktische Korrektheit
*/
private void read_in_Anrede()
{
System.out.println("(z.B. Frau oder Herr)");
anrede = Input.readString("Anrede: ","(Herr|Frau)",
"Diese Anrede wird leider nicht akzeptiert, bitte geben Sie Herr oder Frau ein! ");
}
/**
* überprüft die eingegebene Strasse mithilfe des angegebenen regulären Ausdrucks
* auf syntaktische Korrektheit
*/
private void read_in_Strasse()
{
System.out.println("(z.B. Musterstrasse 1)");
System.out.println("(oder Unterer Hofweg 1)");
strasse = Input.readString("Strasse: ",
"([A-ZÖÜ][a-zöüß]+[/ ][0-9]+)|([A-ZÖÜ][a-zöüß]+[/ ][A-ZÖÜ][a-zöüß]+[/ ][0-9]+)",
"\nGeben Sie Ihre Strasse bitte nach dem Muster des angezeigten Beispiels ein!");
}
/**
* überprüft die eingegebene Postleitzahl mithilfe des angegebenen regulären Ausdrucks
* auf syntaktische Korrektheit
*/
private void read_in_Plz()
{
System.out.println("(z.B. D-12345)");
plz = Input.readString("PLZ: ", "[A-Z]+[-][0-9]{1,5}",
"\nGeben Sie Ihre PLZ bitte nach dem Muster des angezeigten Beispiels ein!");
}
/**
* überprüft den eingegebenen Ort mithilfe des angegebenen regulären Ausdrucks
* auf syntaktische Korrektheit
*/
private void read_in_Ort()
{
System.out.println("(z.B. Musterort)");
ort = Input.readString("Ort: ", "([A-Z][a-z]+)|([A-ZÖÜ][a-zöü]+)",
"\nGeben Sie Ihren Ort bitte nach dem Muster des angezeigten Beispiels ein!");
}
/**
* überprüft die eingegebene Telefonnummer mithilfe des angegebenen regulären Ausdrucks
* auf syntaktische Korrektheit
*/
private void read_in_Telefon()
{
System.out.println("(z.B. +49 12345-12345");
System.out.println("(z.B. 12345-12345");
telefon = Input.readString("Telefon: ", "([/+][0-9]{2}[/ ])?[0-9]+[/-][0-9]+",
"\nGeben Sie Ihre Telefonnummer bitte nach dem Muster des angezeigten Beispiels ein!");
}
/**
* überprüft die eingegebene Faxnummer mithilfe des angegebenen regulären Ausdrucks
* auf syntaktische Korrektheit
*/
private void read_in_Fax()
{
System.out.println("(z.B. +49 12345-12345)");
System.out.println("(oder 12345-12345");
fax = Input.readString("Fax: ", "([/+][0-9]{2}[/ ])?[0-9]+[/-][0-9]+",
"\nGeben Sie Ihre Faxnummer bitte nach dem Muster des angezeigten Beispiels ein!");
}
/**
* überprüft die eingegebene Bemerkung mithilfe des angegebenen regulären Ausdrucks
* auf syntaktische Korrektheit
*/
private void read_in_Bemerkung()
{
System.out.println("Sie muessen nichts eingeben!");
bemerkung = Input.readString("Bemerkung: ");
}
/**
* Sammlung von Methoden
*/
public Person readPerson()
{
read_in_Name();
read_in_Vorname();
read_in_Anrede();
read_in_Strasse();
read_in_Plz();
read_in_Ort();
read_in_Telefon();
read_in_Fax();
read_in_Bemerkung();
return null;
}
/**
* Ueberschriebene toString-Methode zur angepassten Ausgabe von Personenobjekten.
*/
public String toString()
{
String out = "Name: " + name + "\nVorname: " + vorname
+ "\nAnrede: " + anrede + "\nStrasse: " + strasse + "\nPLZ: "
+ plz + "\nOrt: " + ort + "\nTelefon: " + telefon + "\nFax:"
+ fax + "\nBemerkung: " + bemerkung;
return out;
}
}
import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;
/**
* Die Klasse ViewThread gibt das Hauptmenü aus. Das Hauptmenü wird
* anschliessend per Socket an den Server geschickt.
* Über Pipes findet die Kommunikation zwischen ControlerThread und
* ViewThread statt.
* @author zengin
*/
public class ViewThread extends Thread
{
private PipedReader reader;
private PipedWriter writer;
/**
* @param reader
* @param writer
* Der Konstruktor ViewThread mit 2 Parameterübergaben (PipedReader und PipedWriter).
* PipedReader reader ist dazu da, um die Eingaben aus einem beliebigen Reader zu lesen.
* PipedWriter writer ist dazu da, um die Ausgabe in einen beliebigen Writer zu schreiben.
*/
public ViewThread(PipedReader reader, PipedWriter writer)
{
super("ViewThread");
this.reader = reader;
this.writer = writer;
}
/**
* Diese überschriebene run-Methode der Thread-Klasse ruft
* die Methode hauptmenu auf und führt diese anschliessend aus.
*/
public void run()
{
hauptmenu();
}
/**
* Das Hauptmenü wird auf der Konsole angezeigt.
* Innerhalb des try-Blocks findet die Kommunikation der Pipes statt.
* Es werden die Eingaben an die Klasse ModelThread über das Objekt
* PipedWriter geschickt.
* Anschliessend wird aus der Klasse ModelThread über das Objekt
* PipedReader gelesen.
*/
public void hauptmenu()
{
while(true)
{
System.out.println("\r===========================");
System.out.println(" ADRELI - Adressverwaltung ");
System.out.println("===========================");
System.out.println();
System.out.println("Wollen Sie...");
System.out.println();
//BILDSCHIRMMENUE
System.out.println(" eine neue Person aufnehmen: > 1");
System.out.println(" Records auflisten: > 2");
System.out.println("Records in eine Datei sichern: > 3");
System.out.println(" Datei löschen: > 4");
System.out.println(" das Programm verlassen: > 5");
int a = Input.readInt();
System.out.println("------------------------------------");
System.out.println();
if (a == 5) {
System.out.println("\n" + "\n" + "Sie haben das Programm erfolgreich verlassen.");
System.exit(1);
} else {
try
{
writer.write(a);
reader.read();
}
catch(IOException io)
{
System.out.println("Fehler in ViewThread:" + "\n" + io.getMessage());
}
}
}
}
}
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.i

utputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.ArrayList;
import java.util.Date;
/**
* Die Klasse Controller des Servers bietet die Kommunikation des Clients mit
* dem Server über den Socket 12345. Außderdem kontrolliert er die Pipe-
* Kommunikation zwischen den Threads des Servers. Bei jeder Aktivität erstellt
* der Controller einen neuen Eintrag im Log-File 'logfile.csv'mit Zeitstempel.
* @author zengin
*/
public class Server {
File serverdatei = new File("logfile.csv");
private static ArrayList<String> eintragsliste = new ArrayList<String>();
/**
* Die Main kümmert sich um die Kommunikation des Servers mit dem Client via
* Sockets und erstellt auch ein zu Beginn leeres Logfile. Außerdem regelt
* sie den Datenverkehr der Threads des Servers. Hier wird ein Zeit- und
* Datumsformat definiert, dass dann auf der Konsole zu den einzelnen
* Aktionen angezeigt und im Logfile gespeichert wird.
*
* @param args
* @throws IOException
*/
public static void main(String[] args) throws Exception {
System.out.println(">>> Der Server wird gestartet");
@SuppressWarnings("resource")
ServerSocket myServerSocket = new ServerSocket(45678);
while (true) {
Socket myClientSocket = myServerSocket.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(
myClientSocket.getInputStream()));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
myClientSocket.getOutputStream()));
Calendar cal = Calendar.getInstance();
SimpleDateFormat formater = new SimpleDateFormat("HH:mm:ss ");
System.out.println( formater.format(cal.getTime()) );
Date currentTime = new Date();
String anmeldung = formater.format(currentTime) + ";"
+ "Angemeldet an lokaler Adresse" + ";"
+ myClientSocket.getLocalAddress() + "\n";
eintragsliste.add(anmeldung);
schreibeLog(eintragsliste);
System.out.println("--> Local Address angemeldet: "
+ myClientSocket.getLocalAddress());
String s;
try {
while ((s = br.readLine()) != null)
{
int a = Integer.parseInt(s);
if ((a < 6) && (a > 0)) {
formater = new SimpleDateFormat("HH:mm:ss ");
currentTime = new Date();
auswahl(a, currentTime);
schreibeLog(eintragsliste);
System.out.println("> " + formater.format(currentTime)
+ "\n" + "Sie haben den Menuepunkt \'"
+ a + "\' ausgewaehlt");
bw.write("okay");
bw.newLine();
bw.flush();
} else {
auswahl(a, currentTime);
schreibeLog(eintragsliste);
System.out.println("> " + formater.format(currentTime)
+ "\n" + "Ungueltige Eingabe!");
bw.write("nicht okay");
bw.newLine();
bw.flush();
}
}
}
catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println("<-- LocalAddress: "
+ myClientSocket.getLocalAddress());
currentTime = new Date();
String abmeldung = formater.format(currentTime) + ";"
+ "Abgemeldet von der lokalen Adresse" + ";"
+ myClientSocket.getLocalAddress() + "\n";
eintragsliste.add(abmeldung);
schreibeLog(eintragsliste);
myClientSocket.close();
}
}
/**
* Diese Methode formatiert die Log-File Einträge und fügt diese dann durch
* den Aufruf der Methode 'schreibeLog' dem Log-File 'logfile.csv' hinzu.
*
* @param a
* @param zeit
*/
public static void auswahl(int a, Date zeit) {
StringBuilder gebeString = new StringBuilder();
gebeString.append(zeit);
gebeString.append(";");
switch (a) {
case 1:
gebeString.append("Menüpunkt ");
gebeString.append(a);
gebeString.append(";");
gebeString.append("neue Person aufnehmen");
gebeString.append(";");
break;
case 2:
gebeString.append("Menüpunkt ");
gebeString.append(a);
gebeString.append(";");
gebeString.append("Records auflisten");
gebeString.append(";");
break;
case 3:
gebeString.append("Menüpunkt ");
gebeString.append(a);
gebeString.append(";");
gebeString.append("Records in eine Datei sichern");
gebeString.append(";");
break;
case 4:
gebeString.append("Menüpunkt ");
gebeString.append(a);
gebeString.append(";");
gebeString.append("Datei löschen");
gebeString.append(";");
break;
default:
break;
}
gebeString.append("\n");
eintragsliste.add(gebeString.toString());
}
/**
* Diese Methode schreibt die Einträge in die serverdatei "logfile.csv".
*/
public static void schreibeLog(ArrayList<String> eintragsliste) {
try {
BufferedWriter bw = new BufferedWriter(new FileWriter("logfile.csv"));
for (int i = 0; i < eintragsliste.size(); i++) {
bw.write(eintragsliste.get(i));
}
bw.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}