Hallo zusammen!
Ich bin momentan gerade dabei ein kleines Java AWT-Programm mit Client-Server Architektur zu erstellen.
Das Programm enthält die Klassen:
Server: Läuft auf einem eigenständigen Thread um Clients zu akzeptieren
ServerThread: Für jeden akzeptierten Client wird ein eigener Server-Thread erstellt
Client
Des Weiteren gibt es noch:
ClientFenster: GUI für Clienten
ServerFenster: GUI für Server
MeinDialog: Notwendig für Pop-Ups in GUI-Fenstern.
Der Client kann momentan Personen aufnehmen, anzeigen und als (.CSV) Datei abspeichern. Anschließend kann die Datei wieder eingelesen werden. Die Funktionen für die Aufnahme und Anzeige von Personen befinden sich in der Client-Klasse. Die Funktionen Datei speichern sowie Datei laden befinden sich in der Server-Klasse.
1. Im Clienten wird die Funktion menueAuswahl(int auswahl) aufgerufen (Funktion enthält eine switch-case Anweisung)
2. Der passende case-Nummer wurde vorher über die Client-GUI übergeben
3. Die case-Nummer wird anschließend über einen einfachen Outputstream ( out.write() ) vom Client auf einen Socket geschrieben. Die ServerThread-Klasse empfängt die case-Nummer mit einem einfachen in.read() und wählt in ihrer eigenen switch-case Anweisung den passenden Case und damit die entsprechende Funktion aus.
Erwähnenswert sind noch die Methoden toInputStream() und toOutputStream() (enthält ObjectInput bzw. ObjectOutputStreams).
Es werden bspw. die vom Client erstellten Personenobjekte sowie ein paar andere benötigte Variablen (Dateiverzeichnis, Dateiname) über toOutputStream() an den Server schickt, welcher die Daten über den toInputStream() empfängt. Der Server schickt die die aus der geladenen Datei gespeicherten Personenobjekte wiederum über toOutputStream() über den Socket an den Clienten.
Was funktioniert?
An sich funktioniert das Programm insofern, dass sich ein Client mit dem Server verbinden kann und der Client Personen speichert und abruft. Hier gibt es keinerlei Probleme.
Nachfolgend das Problem:
Sobald sich aber bspw. 2 oder Clienten mit dem Server verbinden und beide Clienten gleichzeitig eine Datei speichern oder laden möchten (sprich, mit dem Server kommunizieren), friert eines der beiden Client-Fenster ein.
Ich bin mir sicher, dass ich mich mit den Streams etwas verhauen habe, sprich dass die Streams vom ersten Clienten die Streams vom zweiten, parallel laufenden, blockieren. Ich komme aber einfach nicht dahinter wo der Fehler liegt.
Ich bin mit meinem Latein gerade am Ende und wäre äußerst dankbar, wenn sich jemand von euch die Sache mal anschauen und mir zeigen könnte, wo ich mich verhaspelt habe.
Nachfolgend der Code:
Den Code gibt es hier auch aufgeteilt: https://www.file-upload.net/gal-246339/otvkhz/1.html
Und hier als vollständiges Eclipse-Projekt: https://www.file-upload.net/download-13169109/ADRELI_4_CON.rar.html
Server-Klasse + ServerThread-Klasse:
Client-Klasse
ServerFenster Klasse
Ich bin momentan gerade dabei ein kleines Java AWT-Programm mit Client-Server Architektur zu erstellen.
Das Programm enthält die Klassen:
Server: Läuft auf einem eigenständigen Thread um Clients zu akzeptieren
ServerThread: Für jeden akzeptierten Client wird ein eigener Server-Thread erstellt
Client
Des Weiteren gibt es noch:
ClientFenster: GUI für Clienten
ServerFenster: GUI für Server
MeinDialog: Notwendig für Pop-Ups in GUI-Fenstern.
Der Client kann momentan Personen aufnehmen, anzeigen und als (.CSV) Datei abspeichern. Anschließend kann die Datei wieder eingelesen werden. Die Funktionen für die Aufnahme und Anzeige von Personen befinden sich in der Client-Klasse. Die Funktionen Datei speichern sowie Datei laden befinden sich in der Server-Klasse.
1. Im Clienten wird die Funktion menueAuswahl(int auswahl) aufgerufen (Funktion enthält eine switch-case Anweisung)
2. Der passende case-Nummer wurde vorher über die Client-GUI übergeben
3. Die case-Nummer wird anschließend über einen einfachen Outputstream ( out.write() ) vom Client auf einen Socket geschrieben. Die ServerThread-Klasse empfängt die case-Nummer mit einem einfachen in.read() und wählt in ihrer eigenen switch-case Anweisung den passenden Case und damit die entsprechende Funktion aus.
Erwähnenswert sind noch die Methoden toInputStream() und toOutputStream() (enthält ObjectInput bzw. ObjectOutputStreams).
Es werden bspw. die vom Client erstellten Personenobjekte sowie ein paar andere benötigte Variablen (Dateiverzeichnis, Dateiname) über toOutputStream() an den Server schickt, welcher die Daten über den toInputStream() empfängt. Der Server schickt die die aus der geladenen Datei gespeicherten Personenobjekte wiederum über toOutputStream() über den Socket an den Clienten.
Was funktioniert?
An sich funktioniert das Programm insofern, dass sich ein Client mit dem Server verbinden kann und der Client Personen speichert und abruft. Hier gibt es keinerlei Probleme.
Nachfolgend das Problem:
Sobald sich aber bspw. 2 oder Clienten mit dem Server verbinden und beide Clienten gleichzeitig eine Datei speichern oder laden möchten (sprich, mit dem Server kommunizieren), friert eines der beiden Client-Fenster ein.
Ich bin mir sicher, dass ich mich mit den Streams etwas verhauen habe, sprich dass die Streams vom ersten Clienten die Streams vom zweiten, parallel laufenden, blockieren. Ich komme aber einfach nicht dahinter wo der Fehler liegt.
Ich bin mit meinem Latein gerade am Ende und wäre äußerst dankbar, wenn sich jemand von euch die Sache mal anschauen und mir zeigen könnte, wo ich mich verhaspelt habe.
Nachfolgend der Code:
Den Code gibt es hier auch aufgeteilt: https://www.file-upload.net/gal-246339/otvkhz/1.html
Und hier als vollständiges Eclipse-Projekt: https://www.file-upload.net/download-13169109/ADRELI_4_CON.rar.html
Server-Klasse + ServerThread-Klasse:
Java:
/*
* Copyright (c) 2018
* Client.Java
* @author J. Timmer
* @version 1.7
*
*/
package adreli_4_con;
import java.net.*;
import java.io.*;
import java.util.*;
public class Server extends Thread //Server mit Multithreading (je Client ein Thread)
{
static int serverPort = 0;
ServerSocket serverSocket;
ServerThread serverThread;
ArrayList<ServerThread> threadList = new ArrayList<ServerThread>();
static int clientDisconnected;
/**
* @param args
*
* @throws IOException
* @version 2018.11.24
*/
public void run(){
int clients = 0; // durchnummerierung der Clients
// Server-Socket einstellen und an Port mit binden
try {
serverSocket = new ServerSocket(serverPort);
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
System.out
.println("...Server wurde gestartet, "
+ "warte auf Client-Verbindungen");
while (true) { // wenn keine Verbindung
// hergestellt werden soll wird accept() blockiert
try {
serverThread = new ServerThread(serverSocket.accept(),
++clients, serverSocket);
}
catch (SocketException e) {
break;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
break;
}
serverThread.start();
System.out.println("...warte auf weitere Client-Verbindungen");
}
}
public void stoppen() throws IOException {
try {
this.serverSocket.close();
} catch (NullPointerException e) {
}
if(ServerThread.clientSocket != null) {
ServerThread.clientSocket.close();
}
try {
for (ServerThread threads : threadList)
threads.interrupt();
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("Server konnte nicht gestoppt werden!");
}
this.interrupt();
}
}
class ServerThread extends Thread
{ // ServerThread
static public int persCounter = 0; //zaehlt die erfassten Personen
static public int eingelesen = 0;
static String directory = null;
static String fileName = null;
int serverStatus = 1;
//Puffer fuer erfassen der Personendaten
static String myNewPerson[] = new String[9];
//Puffer fuer die gesammelten Daten
static String myPersons[][] = new String[10][9];
LinkedList<Person> myPersonObjects = new LinkedList<>();
//Sockets & Streams
public static Socket clientSocket;
ServerSocket serverSocket;
private static InputStream in;
static OutputStream out;
int clientNumber; // zugewiesene Nummer des verbundenen Clients
/**
* @param clientSocket Socket über den gestreamt wird
* @param clientNumber Durchnummerierung der Clients für leichtere Zurodnung
* @throws IOException
*/
public ServerThread(Socket clientSocket, int clientNumber, ServerSocket serverSocket)
throws IOException {
this.clientSocket = clientSocket;
this.clientNumber = clientNumber;
this.serverSocket = serverSocket;
in = clientSocket.getInputStream();
out = clientSocket.getOutputStream();
clientNumber -= Server.clientDisconnected;
System.out.println("--> Client " + clientNumber + " angemeldet");
}
public void run() {
boolean dauer=true;
int eingabe = 0;
while (dauer != false){
try {
toInputStream();
try {
eingabe = in.read();
}
catch (SocketException e) {
break;
}
switch (eingabe) {
case 3: //Records in Datei sichern
personSpeichern();
break;
case 4: //Records aus Datei laden
dateiEinlesen();
toOutputStream();
break;
case 8: //Serverstatusanfrage von Client
toOutputStream();
break;
}
} catch(IOException e) {
e.printStackTrace();
}
}
}
/**
*
* Die vom View-Thread uebergebene Linked-List mit Personenobjekten wird
* direkt ausgelesen und die Inhalte in eine Random Access File
* geschrieben (auf das uebertragen der Inhalte der aus dem Socket geholten
* Linked-List in ein String-Array wird aus Perfomancegruenden verzichtet).
*
*/
private void personSpeichern() throws IOException { //funct_3()
System.out.println("Hier ist die Funktion personSpeichern()");
//betriebsspezifische Lineoperator, / oder \, je nach Betriebssystem
final String NEWLINE = System.getProperty("line.separator");
RandomAccessFile raf;
raf = new RandomAccessFile(directory+fileName, "rw");
try {
for (int i = 0; i < persCounter; i++) {// Schreib-Schleife
raf.writeBytes(myPersonObjects.get(i).getName());
raf.writeBytes(";");
raf.writeBytes(myPersonObjects.get(i).getVorname());
raf.writeBytes(";");
raf.writeBytes(myPersonObjects.get(i).getAnrede());
raf.writeBytes(";");
raf.writeBytes(myPersonObjects.get(i).getStrasse());
raf.writeBytes(";");
raf.writeBytes(myPersonObjects.get(i).getPlz());
raf.writeBytes(";");
raf.writeBytes(myPersonObjects.get(i).getOrt());
raf.writeBytes(";");
raf.writeBytes(myPersonObjects.get(i).getTelefon());
raf.writeBytes(";");
raf.writeBytes(myPersonObjects.get(i).getFax());
raf.writeBytes(";");
raf.writeBytes(myPersonObjects.get(i).getBemerkung());
raf.writeBytes(NEWLINE);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally
{
try {
raf.close();
}
catch(IOException e)
{
System.out.println("Filewriter konnte"
+ " nicht geschlossen werden!");
e.printStackTrace();
}
}
}
/**
* Records aus der Datei Adreli.CSV werden eingelesen und in
* das String-Array myPersons[][] geladen.
* Die Datei wird zeilenweise gelesen, wobei die
* eingelese Zeile zunaechst in das
* String-Array myNewPerson[] geschrieben wird.
* Dieser Zeilenpuffer wird mit
* der Methode split() (class RandomAccessFile) in Einzelfelder zerlegt.
* Einzelfelder sind durch ";" getrennt.
* Mit diesen Einzelfeldern wird dann der Gesamtpuffer myPersons[][]
* aufgebaut/gefuellt.
*
* Anschließend werden mit den Personendaten der String-Matrix
* Personenobjekte ueber arrayToObject() erstellt und in die Linked-List
* myPersonobjects uebertragen.
*/
private void dateiEinlesen() { //funct_4() Records aus Datei laden
System.out.println("Hier ist die Funktion dateiEinlesen()");
eingelesen = 0; //eingelesene Personen
persCounter = 0; //"persCounter" ist größer als "eingelesen", da
//"eingelesen" nicht die beim Clienten aufgenommenen
//Personen berücksichtigt, die Differenz zwischen
//"persCounter" und "eingelesen" wird später bei der
//korrekten Auswahl der Konsolenausgabe benötigt
int zeile = 0; //Zeilen-Index fuer unsere Puffermatrix myPersons[][]
Scanner einlesen = null; //leeres Scanner-Objekt
try {//Scanner-Objekt einlesen
einlesen = new Scanner(new File(directory+fileName));
} catch (FileNotFoundException e) {
}
try {
while (einlesen.hasNextLine()) //Pruefung, ob Zeile vorhanden
{
String myLine = einlesen.nextLine(); //Zeile aus Datei holen
if (myLine == null)
break;
myNewPerson = myLine.split(";"); //myLine aufgeteilt
for (int i = 0; i < myNewPerson.length; i++) {
myPersons[zeile][i] = myNewPerson[i];
}
persCounter++;
eingelesen++;
zeile++; //Zeilenzaehler erhöhen
}
} catch (ArrayIndexOutOfBoundsException ex) {
System.out.println();
System.out.println(
"Es können nur nicht-nummerierte "
+ "Dateien eingelesen werden!");
System.out.println();
}
arrayToObject();
}//end of dateiEinlesen()
/**
*
* Nach einlesen der Inhalte der Datei wurden die Daten zunaechst in einer
* String-Array-Matrix gespeichert, mit der Funktion arrayToObject() werden
* die Inhalte des String-Arrays in Personen-Objekte uebertragen und
* in eine Linked-List gespeichert. Die Linked-List wird anschließend
* mithilfe von outputStream() auf den Socket geschrieben.
*
*/
public void arrayToObject() {
for(int a = myPersonObjects.size(); a < persCounter; a++) {
Person p = new Person();
p.setName(myPersons[a][0]);
p.setVorname(myPersons[a][1]);
p.setAnrede(myPersons[a][2]);
p.setStrasse(myPersons[a][3]);
p.setPlz(myPersons[a][4]);
p.setOrt(myPersons[a][5]);
p.setTelefon(myPersons[a][6]);
p.setFax(myPersons[a][7]);
p.setBemerkung(myPersons[a][8]);
myPersonObjects.add(p);
}
}
/**
* Befuellte LinkedList ueber ObjectOutputStream senden
*/
public void toOutputStream()
{
System.out.println("Hier ist die Funktion toInputStream(), Server");
try
{
ObjectOutputStream ou2 = new ObjectOutputStream(out);
ou2.writeObject(myPersonObjects);
ou2.writeObject(serverStatus);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Befuellte LinkedList (zwecks schreiben in Datei)
* ueber ObjectInputStream erhalten.
*
* Nach dem auslesen des Sockets wird direkt persCounter aktualisiert,
* damit alle Funktionen die persCounter implementiert
* haben mit dem korrekten Zählerstand hinsichtlich der
* gespeicherten Personen arbeiten können.
*/
public void toInputStream()
{
System.out.println("Hier ist die Funktion toOutputStream(), Server");
try
{
ObjectInputStream oi2 = new ObjectInputStream(in);
myPersonObjects = (LinkedList <Person>) oi2.readObject();
persCounter = myPersonObjects.size();
directory = (String) oi2.readObject();
fileName = (String) oi2.readObject();
} catch (SocketException e) {
} catch (IOException | ClassNotFoundException e) {
}
}
} // ServerThread
Client-Klasse
Java:
/*
* Copyright (c) 2018
* Client.Java
* @author Jan Timmer
* @version 1.7
*
*/
package adreli_4_con;
import java.io.*;
import java.net.*;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
public class Client
{
static private boolean go_on = true;
static public int persCounter = 0;
static int eingabe = 0;
static String myNewPerson[] = new String[9];
static String myPersons[][] = new String[10][9]; //String-Matrix Puffer
//LinkedList wird später mithilfe der StringMatrix befuellt und
//auf Socket geschrieben
static LinkedList<Person> myPersonObjects = new LinkedList<>();
static String ip;
static int port = 0;
static int serverStatus = 0;
static String directory = null;
static String fileName = null;
static int fileSavedorOpened = 0;
Socket clientSocket = null;
static InputStream in;
static OutputStream out;
//Hilfsgrössen/Hilfskonstanten
final static int NAME = 0;
final static int VORNAME = 1;
final static int ANREDE = 2;
final static int STRASSE = 3;
final static int PLZ = 4;
final static int ORT = 5;
final static int TELEFON = 6;
final static int FAX = 7;
final static int BEMERKUNG = 8;
/**
* @param args
* @throws IOException
*/
public void starten() throws IOException
{
File f = new File("Adreli.csv"); //prüft, ob Datei vorhanden
//wenn ja, wird vor der Ausführung von
//personAufnehmen() die Datei
//automatisch eingelesen
//(siehe case 1 im Switch)
try {//Abfrage der IP des Servers
try{
clientSocket = new Socket(ip, port);
in = clientSocket.getInputStream();
out = clientSocket.getOutputStream();
ClientFenster.lblMenueInfoUeberschrift2.setText("Verbindung hergestellt!");
} catch(ConnectException e) {
ClientFenster.lblMenueInfoUeberschrift2.setText("Verbindung nicht möglich!");
} catch(IllegalArgumentException e) {
ClientFenster.lblMenueInfoUeberschrift2.setText("Portnummer ungültig!");
}
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
public void menueAuswahl(int auswahl) {
eingabe = auswahl;
try {
switch (eingabe) {
case 1:
personAufnehmen();//Personen in
//myNewPerson[] aufnehmen
arrayToObject();
break;
case 3: //Records in Datei sichern
fileSavedorOpened = 1;
toOutputStream();
out.write(eingabe);
ClientFenster.lblMenueInfoUeberschrift2.setText("Datei gespeichert!");
break;
case 4: //Records aus Datei laden
fileSavedorOpened = 1;
toOutputStream();
out.write(eingabe);
out.flush();
toInputStream();
ClientFenster.lblMenueInfoUeberschrift2.setText("Datei geladen!");
break;
case 8: //Serverstatus abfragen
toOutputStream();
out.write(eingabe);
toInputStream();
break;
}
} catch(SocketException e) {
serverStatus = 2;
} catch(IOException e) {
e.printStackTrace();
}
}
/**
* Die Person wird zunaechst ueber Funktion 1
* auf der Konsole abgefragt und anschließend in
* einem einfachem Array gespeichert. Mit Funktion 2 werden die Inhalte des
* einfachen Arrays in eine Matrix uebernommen.
* Anschließend werden mit arrayToObject() die Matrixinhalte
* in Personenobjekte uebertragen und die Objekte darauffolgend in einer
* Linked-List gespeichert. Die mit Personenobjekten
* gefuellte Linked-List wird dann bei Aufruf einer entsprechenden Funktion
* mithilfe von outputStream() auf den Socket geschrieben.
*
* Die Form der Personendaten ist durch die Nutzung von Patterns
* vorgeschrieben.
*/
public static void personAufnehmen(){ //Funktion 1
System.out.println("Hier ist die Funktion personAufnehmen(), Client");
boolean loop = true; //steuert die folgende while-Schleife
boolean ok = false;
boolean nochmal = false;
int error = 0;
try {
String a ="[A-ZÄÖÜ]{1}([a-zäöüß]+)(\\s(\\-|";
String b ="(von))\\s[A-ZÄÖÜ]{1}([a-zäöüß]+))?";
String c = a+b;
Pattern namePattern = Pattern.compile(c);
Pattern vornamePattern = Pattern.compile("([A-Z]{1}[a-z]+)+");
Pattern anredePattern = Pattern.compile("((Herr)|(Frau))");
a = "[A-Z]{1}[a-z]+(\\.|\\-|\\s){1}[A-Z]{0,1}[a-z]*";
b = "(\\.?\\-?)(Str.)?[1-9]+[0-9]?";
c = "(([a-z]|\\-?|([1-9][0-9]))?)";
String d = a + b + c;
Pattern strassePattern = Pattern.compile(d);
Pattern plzPattern = Pattern.compile("([A-Z]{1,2}\\-)"
+ "?[0-9]{4,5}");
//4 oder 5-stellige PLZ
a ="^[a-zäöüßA-ZÄÖÜ]+(?:[\\s-]";
b = "[a-zäöüßA-ZÄÖÜ]+)*$";
c = a + b;
Pattern ortPattern = Pattern.compile(c);
a = "(?:\\(\\+?\\d+\\)|\\+?\\d+)";
b = "(?:\\s*[\\-\\/]*\\s*\\d+)+";
c = a + b;
Pattern telefonPattern = Pattern.compile(c);
Pattern faxPattern = Pattern.compile(c);
//Fuer den Vergleich werden fuer jedes Attribut
//je 2 Variablen erstellt
String xName;
String xVorname;
String xAnrede;
String xStrasse;
String xPLZ;
String xOrt;
String xTelefon;
String xFax;
Matcher yName;
Matcher yVorname;
Matcher yAnrede;
Matcher yStrasse;
Matcher yPLZ;
Matcher yOrt;
Matcher yTelefon;
Matcher yFax;
//Name
xName = ClientFenster.txtName.getText();
yName = namePattern.matcher(xName);
if(yName.matches())
{
myNewPerson[0] = xName;
}else
{
ClientFenster.lblPers_NameAusgabe.setText("Eingabe ungueltig! "
+ "Erster Buchstabe groß?");
error = 1;
}
//Vorname
xVorname = ClientFenster.txtVorname.getText();
yVorname = vornamePattern.matcher(xVorname);
if(yVorname.matches())
{
myNewPerson[1] = xVorname;
}
else
{
ClientFenster.lblPers_VornameAusgabe.setText("Eingabe ungueltig! "
+ "Erster Buchstabe groß?");
error = 1;
}
//Anrede
xAnrede = ClientFenster.txtAnrede.getText();
yAnrede = anredePattern.matcher(xAnrede);
if(yAnrede.matches())
{
myNewPerson[2] = xAnrede;
}
else
{
ClientFenster.lblPers_AnredeAusgabe.setText("Eingabe ungueltig! Zulässig: Herr/Frau");
error = 1;
}
//Straße
xStrasse = ClientFenster.txtStrasse.getText();
yStrasse = strassePattern.matcher(xStrasse);
if(yStrasse.matches())
{
myNewPerson[3] = xStrasse;
}
else
{
ClientFenster.lblPers_StrasseAusgabe.setText("Eingabe ungueltig! "
+ "Erster Buchstabe groß?");
error = 1;
}
//PLZ
xPLZ = ClientFenster.txtPLZ.getText();
yPLZ = plzPattern.matcher(xPLZ);
if(yPLZ.matches())
{
myNewPerson[4] = xPLZ;
}
else
{
ClientFenster.lblPers_PLZAusgabe.setText("Eingabe ungueltig! Korrekte PLZ?");
error = 1;
}
//Ort
xOrt = ClientFenster.txtOrt.getText();
yOrt = ortPattern.matcher(xOrt);
if(yOrt.matches())
{
myNewPerson[5] = xOrt;
}
else
{
ClientFenster.lblPers_OrtAusgabe.setText("Eingabe ungueltig! "
+ "Erster Buchstabe groß?");
error = 1;
}
//Telefon
xTelefon = ClientFenster.txtTelefon.getText();
yTelefon = telefonPattern.matcher(xTelefon);
if(yTelefon.matches())
{
myNewPerson[6] = xTelefon;
}
else
{
ClientFenster.lblPers_TelefonAusgabe.setText("Eingabe ungueltig!");
error = 1;
}
//Fax
xFax = "4423443";
yFax = faxPattern.matcher(xFax);
if(yFax.matches())
{
myNewPerson[7] = xFax;
}
else
{
ClientFenster.lblPers_FaxAusgabe.setText("Eingabe ungueltig!");
error = 1;
}
//Bemerkung
myNewPerson[8] = ClientFenster.txtBemerkung.getText();
}
catch (PatternSyntaxException ex) {
}
if(error == 0) {
matrix_befuellen();
ClientFenster.lblPersonAufnahme_InfoBox.setText("Person Nr. " +Client.persCounter
+" aufgenommen!");
}
else {
ClientFenster.lblPersonAufnahme_InfoBox.setText("Person konnte "
+ "nicht aufgenommen werden. Eingaben überprüfen!");
}
}//end of personAufnehmen()
private static void matrix_befuellen() { //Funkt 2 myPersons[][] Zeilen
//fuellen
for (int i = 0; i < myNewPerson.length; i++) {
myPersons[persCounter][i] = myNewPerson[i];
}
persCounter++;
}//end of matrix_befuellen()
/**
*
* Die Inhalte der Matrix werden ausgelesen und in einzelne
* Personenobjekte uebertragen. Anschließend werden die Personenobjekte
* in einer Linked-List gespeichert.
*
*/
public static void arrayToObject() { //Hilfsmethode
for(int a = myPersonObjects.size(); a < persCounter; a++) {
Person p = new Person();
p.setName(myPersons[a][0]);
p.setVorname(myPersons[a][1]);
p.setAnrede(myPersons[a][2]);
p.setStrasse(myPersons[a][3]);
p.setPlz(myPersons[a][4]);
p.setOrt(myPersons[a][5]);
p.setTelefon(myPersons[a][6]);
p.setFax(myPersons[a][7]);
p.setBemerkung(myPersons[a][8]);
myPersonObjects.add(p);
}
}//end of arrayToObject()
public static void toOutputStream()
{
System.out.println("Hier ist die Funktion toOutputStream(), Client");
try
{
ObjectOutputStream ou1 = new ObjectOutputStream(out);
ou1.writeObject(myPersonObjects);
ou1.writeObject(directory);
ou1.writeObject(fileName);
} catch (SocketException e) {
ClientFenster.lblMenueInfoUeberschrift2.setText("Server killed!");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*
* Nach dem auslesen des Sockets wird direkt persCounter aktualisiert,
* damit alle Funktionen die persCounter implementiert haben mit dem
* korrekten Zählerstand hinsichtlich der gespeicherten
* Personen arbeiten können.
*
*/
public static void toInputStream()
{
System.out.println("Hier ist die Funktion toInputStream(), Client");
try
{
ObjectInputStream oi1 = new ObjectInputStream(in);
myPersonObjects = (LinkedList <Person>) oi1.readObject();
persCounter = myPersonObjects.size();
serverStatus = (int) oi1.readObject();
} catch (IOException | ClassNotFoundException ex) {
ex.printStackTrace();
}
}
}
ServerFenster Klasse
Java:
/*
* Copyright (c) 2018
* Client.Java
* @author Jan Timmer
* @version 1.7
*
*/
package adreli_4_con;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class ServerFenster extends Frame implements ActionListener, ItemListener{
Button btnKonfigAbsenden;
Button btnPortÄndern;
Button btnServerStart;
Button btnServerFunktionen;
Button btnZurueckServerFunktionen;
Button btnDatenbasis;
Button btnDatenbank;
Button btnTextdatei;
Button btnZurueckDatenbasis;
Button btnServerStopp;
Button btnServerlog;
Button btnZurueckServerLog;
Button btnBeenden;
Label lblPortEingabe;
Label lblHauptmenueUeberschrift;
Label lblmenueInfoUeberschrift;
Label lblDatenbasis;
Label lblServerLog;
Label lblAktuellerPort;
static Label lblmenueInfoUeberschrift2;
TextField txtPortEingabe;
static TextField txtServerStartInfoAusgabe;
static TextField txtServerStoppInfoAusgabe;
TextArea txtServerLogAusgabefeld;
Server s1 = new Server();
String logCompleteToString = new String();
int serverStatus = 0;
public static void main(String[] args) throws IOException {
ServerFenster fenster = new ServerFenster();
}
public ServerFenster()
{
setTitle("Server-Assistent V1.0");
this.setSize(700, 300);
this.setLocation(600, 300);
this.setBackground(Color.DARK_GRAY);
this.setLayout(null);
MenuBar mnuBar = new MenuBar();
this.setMenuBar(mnuBar);
lblHauptmenueUeberschrift = new Label();
lblHauptmenueUeberschrift.setSize(226,23);
lblHauptmenueUeberschrift.setLocation(60, 40);
lblHauptmenueUeberschrift.setFont(new Font("Times New Roman", Font.PLAIN, 22));
lblHauptmenueUeberschrift.setText("Server Mission Control");
lblHauptmenueUeberschrift.setBackground(Color.DARK_GRAY);
lblHauptmenueUeberschrift.setForeground(Color.white);
this.add(lblHauptmenueUeberschrift);
lblmenueInfoUeberschrift = new Label("Anzahl Clients:");
lblmenueInfoUeberschrift.setSize(140, 23);
lblmenueInfoUeberschrift.setLocation(520, 65);
lblmenueInfoUeberschrift.setFont(new Font("Times New Roman", Font.PLAIN, 14));
lblmenueInfoUeberschrift.setBackground(Color.GRAY);
lblmenueInfoUeberschrift.setForeground(Color.white);
this.add(lblmenueInfoUeberschrift);
lblmenueInfoUeberschrift2 = new Label("0");
lblmenueInfoUeberschrift2.setSize(140, 23);
lblmenueInfoUeberschrift2.setLocation(520, 88);
lblmenueInfoUeberschrift2.setFont(new Font("Times New Roman", Font.PLAIN, 14));
lblmenueInfoUeberschrift2.setBackground(Color.LIGHT_GRAY);
lblmenueInfoUeberschrift2.setForeground(Color.black);
this.add(lblmenueInfoUeberschrift2);
this.setVisible(true);
showHauptmenueFenster();
this.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent we)
{
System.exit(0);
}
});
}
public void showHauptmenueFenster() {
serverFunktionen();
auswahlDatenbasis();
btnServerlog();
btnBeenden();
}
public void serverFunktionen(){
btnServerFunktionen = new Button("Serverfunktionen");
btnServerFunktionen.setCursor(new Cursor(Cursor.HAND_CURSOR));
btnServerFunktionen.setBounds(300,100, 100, 23);
this.add(btnServerFunktionen);
btnServerFunktionen.addActionListener(this);
}
public void serverStart(){
btnServerStart = new Button("Serverstart");
btnServerStart.setCursor(new Cursor(Cursor.HAND_CURSOR));
btnServerStart.setBounds(200,120, 100, 23);
this.add(btnServerStart);
btnServerStart.addActionListener(this);
txtServerStartInfoAusgabe = new TextField("Server gestoppt!");
txtServerStartInfoAusgabe.setSize(150,23);
txtServerStartInfoAusgabe.setLocation(330, 120);
txtServerStartInfoAusgabe.setBackground(Color.red);
//serverStartAusgabe.setForeground(Color.white);
txtServerStartInfoAusgabe.setFont(new Font("Arial", Font.BOLD, 12));
txtServerStartInfoAusgabe.setEditable(false);
this.add(txtServerStartInfoAusgabe);
btnKonfigAbsenden = new Button("Aendern");
btnKonfigAbsenden.setCursor(new Cursor(Cursor.HAND_CURSOR));
btnKonfigAbsenden.setBounds(500,170, 100, 23);
btnKonfigAbsenden.setFont(new Font("Arial", Font.BOLD, 12));
this.add(btnKonfigAbsenden);
btnKonfigAbsenden.addActionListener(this);
lblPortEingabe = new Label("Port eingeben:", Label.CENTER);
lblPortEingabe.setSize(100, 23);
lblPortEingabe.setLocation(200,170);
lblPortEingabe.setBackground(Color.white);
this.add(lblPortEingabe);
txtPortEingabe = new TextField("56789");
txtPortEingabe.setSize(150, 23);
txtPortEingabe.setLocation(330, 170);
add(txtPortEingabe);
lblAktuellerPort = new Label("Aktueller Server Port: " +s1.serverPort);
lblAktuellerPort.setSize(155,23);
lblAktuellerPort.setLocation(250, 200);
lblAktuellerPort.setBackground(Color.DARK_GRAY);
lblAktuellerPort.setForeground(Color.white);
this.add(lblAktuellerPort);
}
public void serverStopp(){
btnServerStopp = new Button("Serverstopp");
btnServerStopp.setCursor(new Cursor(Cursor.HAND_CURSOR));
btnServerStopp.setBounds(200,120, 100, 23);
this.add(btnServerStopp);
btnServerStopp.addActionListener(this);
txtServerStoppInfoAusgabe = new TextField("Server gestartet!");
txtServerStoppInfoAusgabe.setSize(150,23);
txtServerStoppInfoAusgabe.setLocation(330, 120);
txtServerStoppInfoAusgabe.setBackground(Color.green);
txtServerStoppInfoAusgabe.setFont(new Font("Arial", Font.BOLD, 12));
txtServerStoppInfoAusgabe.setEditable(false);
this.add(txtServerStoppInfoAusgabe);
}
private void btnServerlog() {
btnServerlog = new Button("Serverlog");
btnServerlog.setCursor(new Cursor(Cursor.HAND_CURSOR));
btnServerlog.setBounds(300,150, 100, 23);
this.add(btnServerlog);
btnServerlog.addActionListener(this);
}
private void ServerLogFenster()
{
//Die Buttons werden angezeigt.
//Ein String fuer den Textfeldinhalt wird eingefuehrt.
String logKomplett = new String();
//Das Label fuer das Log-File wird angezeigt.
lblServerLog = new Label("Server-Log");
lblServerLog.setForeground(Color.white);
lblServerLog.setBackground(Color.GRAY);
lblServerLog.setFont(new Font("Arial", Font.BOLD, 12));
lblServerLog.setSize(70, 23);
lblServerLog.setLocation(300, 90);
this.add(lblServerLog);
//Die Textarea wird angelegt.
txtServerLogAusgabefeld = new TextArea();
txtServerLogAusgabefeld.setSize(450, 200);
txtServerLogAusgabefeld.setLocation(120, 125);
try
{
//Textfile entählt alle Serverlogs
RandomAccessFile file =
new RandomAccessFile("ServerLogfile.txt", "rw");
RandomAccessFile file2 =
new RandomAccessFile("ServerLogfile.txt", "rw");
int lineNumber = 0;
//Anzahl der Zeilen wird gezählt
while (file2.readLine() != null){
lineNumber++;
}
System.out.println("linenumber " +lineNumber);
//Alle vorhandenen Zeilen werden eingelesen und in einem String
//gespeichert
for (int i =0;i < lineNumber;i++)
{
logKomplett = logKomplett + file.readLine()+ "\n";
}
}
catch(IOException io)
{
}
//Im großen Anzeigefeld wird der zuvor befüllte String angezeigt
txtServerLogAusgabefeld.setText(logKomplett);
this.add(txtServerLogAusgabefeld);
}
public void auswahlDatenbasis() {
btnDatenbasis = new Button("Datenbasis");
btnDatenbasis.setCursor(new Cursor(Cursor.HAND_CURSOR));
btnDatenbasis.setSize(100, 23);
btnDatenbasis.setLocation(300, 200);
this.add(btnDatenbasis);
btnDatenbasis.addActionListener(this);
}
public void showDatenbasisFenster() {
btnDatenbank();
btnTextdatei();
btnZurueckDatenbasis();
}
public void btnDatenbank() {
btnDatenbank = new Button("Datenbank");
btnDatenbank.setSize(100, 23);
btnDatenbank.setLocation(210, 160);
btnDatenbank.setFont(new Font("Arial", Font.BOLD, 12));
this.add(btnDatenbank);
btnDatenbank.addActionListener(this);
}
public void btnTextdatei(){
lblDatenbasis = new Label("Welche Datenbasis soll verwendet werden? ");
lblDatenbasis.setFont(new Font("Arial", Font.LAYOUT_LEFT_TO_RIGHT, 14));
lblDatenbasis.setForeground(Color.white);
lblDatenbasis.setSize(300, 23);
lblDatenbasis.setLocation(200, 130);
this.add(lblDatenbasis);
btnTextdatei = new Button("Textdatei");
btnTextdatei.setSize(100, 23);
btnTextdatei.setLocation(360, 160);
btnTextdatei.setFont(new Font("Arial", Font.BOLD, 12));
this.add(btnTextdatei);
btnTextdatei.addActionListener(this);
}
private void btnBeenden()
{
btnBeenden = new Button("Server beenden");
btnBeenden.setSize(120, 23);
btnBeenden.setLocation(540, 235);
Color col_beenden = new Color(254,32,42);
btnBeenden.setBackground(col_beenden);
btnBeenden.setFont(new Font("Arial", Font.BOLD, 12));
this.add(btnBeenden);
btnBeenden.addActionListener(this);
}
public void removeServerstartFenster() {
btnServerStart.removeNotify();
txtServerStartInfoAusgabe.removeNotify();
btnKonfigAbsenden.removeNotify();
lblPortEingabe.removeNotify();
txtPortEingabe.removeNotify();
}
public void removeServerstoppFenster() {
btnServerStopp.removeNotify();
txtServerStoppInfoAusgabe.removeNotify();
lblAktuellerPort.removeNotify();
}
public void removeHauptmenue() {
btnServerFunktionen.removeNotify();
btnDatenbasis.removeNotify();
btnServerlog.removeNotify();
btnBeenden.removeNotify();
}
public void removeAuswahlDatenbasis() {
btnDatenbasis.removeNotify();
lblDatenbasis.removeNotify();
btnDatenbank.removeNotify();
btnTextdatei.removeNotify();
btnZurueckDatenbasis.removeNotify();
}
public void btnZurueckServerFunktionen() {
btnZurueckServerFunktionen = new Button("Zurueck");
btnZurueckServerFunktionen.setCursor(new Cursor(Cursor.HAND_CURSOR));
btnZurueckServerFunktionen.setSize(100, 23);
btnZurueckServerFunktionen.setLocation(40, 238);
btnZurueckServerFunktionen.setFont(new Font("Arial", Font.BOLD, 12));
this.add(btnZurueckServerFunktionen);
btnZurueckServerFunktionen.addActionListener(this);
}
private void btnZurueckDatenbasis(){
btnZurueckDatenbasis = new Button("Zurueck");
btnZurueckDatenbasis.setCursor(new Cursor(Cursor.HAND_CURSOR));
btnZurueckDatenbasis.setSize(100, 23);
btnZurueckDatenbasis.setLocation(40, 238);
btnZurueckDatenbasis.setFont(new Font("Arial", Font.BOLD, 12));
this.add(btnZurueckDatenbasis);
btnZurueckDatenbasis.addActionListener(this);
}
private void btnZurueckServerLog(){
btnZurueckServerLog = new Button("Zurueck");
btnZurueckServerLog.setCursor(new Cursor(Cursor.HAND_CURSOR));
btnZurueckServerLog.setSize(100, 23);
btnZurueckServerLog.setLocation(40, 340);
btnZurueckServerLog.setFont(new Font("Arial", Font.BOLD, 12));
this.add(btnZurueckServerLog);
btnZurueckServerLog.addActionListener(this);
}
public void actionPerformed(ActionEvent ae)
{
Object o = ae.getSource();
if(o instanceof Button) {
/*if(ae.getActionCommand().equals("Absenden")) {
eingabe = txtEingabe.getText();
ausgabeLabel.setText(eingabe);
}*/
if(o.equals(btnKonfigAbsenden)) {
try {
if(Integer.parseInt(txtPortEingabe.getText()) > 65535) {
lblAktuellerPort.setText("Portnummer zu lang!");
return;
}
s1.serverPort = Integer.parseInt(txtPortEingabe.getText());
lblAktuellerPort.setText("Aktueller Server Port: " +s1.serverPort);
btnServerStart.setBackground(Color.orange);
txtServerStartInfoAusgabe.setText("Server startbereit!");
txtServerStartInfoAusgabe.setBackground(Color.green);
txtPortEingabe.setBackground(Color.green);
}
catch(IllegalArgumentException e) {
lblAktuellerPort.setText("Port ungültig!");
}
}
else if(o.equals(btnServerFunktionen)) {
removeHauptmenue();
if(serverStatus == 1) {
serverStopp();
}
else {
serverStart();
}
btnZurueckServerFunktionen();
}
else if(o.equals(btnServerStart)) {
if(s1.serverPort == 0) {
txtServerStartInfoAusgabe.setText("Port zuerst eingeben!");
txtPortEingabe.setBackground(Color.red);
return;
}
if(serverStatus == 0) {
s1 = new Server();
s1.start();
serverStatus = 1;
}
else {
txtServerStartInfoAusgabe.setText("Server bereits gestartet!");
return;
}
removeServerstartFenster();
serverStopp();
}
else if(o.equals(btnServerStopp)) {
try {
s1.stoppen();
s1.interrupt();
lblmenueInfoUeberschrift2.setText("0");
txtServerStartInfoAusgabe.setText("");
serverStatus = 0;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
removeServerstoppFenster();
serverStart();
btnServerStart.setBackground(Color.orange);
txtServerStartInfoAusgabe.setText("Server gestoppt & bereit!");
txtServerStartInfoAusgabe.setBackground(Color.orange);
}
else if(o.equals(btnZurueckServerFunktionen)) {
btnZurueckServerFunktionen.removeNotify();
lblAktuellerPort.removeNotify();
if(serverStatus == 1) {
removeServerstoppFenster();
}
else {
removeServerstartFenster();
}
showHauptmenueFenster();
}
else if(o.equals(btnDatenbasis)) {
removeHauptmenue();
showDatenbasisFenster();
}
else if(o.equals(btnDatenbank)) {
}
else if(o.equals(btnTextdatei)) {
}
else if(o.equals(btnZurueckDatenbasis)) {
removeAuswahlDatenbasis();
showHauptmenueFenster();
}
else if(o.equals(btnServerlog)) {
this.setSize(700, 400);
removeHauptmenue();
btnZurueckServerLog();
ServerLogFenster();
}
else if(o.equals(btnZurueckServerLog)) {
btnZurueckServerLog.removeNotify();
lblServerLog.removeNotify();
txtServerLogAusgabefeld.removeNotify();
this.setSize(700, 300);
showHauptmenueFenster();
}
else if(o.equals(btnBeenden)) {
MeinDialog dlg = new MeinDialog
(this, "Laden-Dialog", "Moechten Sie den Server beenden?");
if(dlg.getAntwort()==true)
{
//Wenn auf ja geklickt wurde, wird das Programm beendet.
System.exit(0);
}
else{
}
}
}
}
@Override
public void itemStateChanged(ItemEvent arg0) {
// TODO Auto-generated method stub
}
public void paint(Graphics g) {
g.setColor(Color.LIGHT_GRAY);
g.drawRect(this.getInsets().left + 20,
this.getInsets().top + 20,
(int)this.getSize().getWidth() - this.getInsets().left -
this.getInsets().right - 40,
(int)this.getSize().getHeight() - this.getInsets().top - this.getInsets().bottom - 40
);
//g.fillRect(20, 50, 655, 225);
//g.fillRect(30, 55, 635, 215);
//g.fillRect(110, 60, 450, 200);
//g.fillRect(135, 90, 415, 140);
}
}//End of Class
Zuletzt bearbeitet: