Letzte Kommentare hinzugefügt, Namen geupdatet und Dateien formatiert.

This commit is contained in:
eichehome 2021-05-16 20:03:38 +02:00
parent c1bb7a2070
commit 8ea1060c44
7 changed files with 703 additions and 530 deletions

View file

@ -1,15 +1,10 @@
package client;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.TextArea;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import utils.Message;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JTextArea;
@ -19,36 +14,48 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;
import java.awt.event.ActionEvent;
public class Client extends JFrame {
/**
* Hauptklasse des Clients
*
* @version 0.1.3
* @author berdan
*/
public class Client1 extends JFrame {
/*
Hier werden Objekte und Variablen deklariert, damit diese
in allen Methoden genutzt werden können.
*/
private static JPanel contentPane;
JTextField txtMessage;
private JTextField txtUsername;
private static JTextField txtUsername;
public static String currentText = " ";
public static int i = 0;
public static Object tosend = new Message("Leer", "Leer");
public static Client t1;
public static Client1 t1;
public static Socket socket;
public static ObjectInputStream obinstr;
public static ObjectOutputStream oboust;
public static boolean verbunden = false;
public static JTextArea textArea = new JTextArea();
public static int anzahlVersuche = 0; //Ist gleich die AN
public static int anzahlRekursionen = 0;
public static Message temp = new Message("leer", "leer");
/**
* Beta Version des Clients
* @version 0.0.2
* @author berdan
/*
In der main Methode wird das GUI erstellt und die
start() Methode aufgerufen.
*/
public static void main(String[] args) {
t1 = new Client();
public static void main(String[] args) throws InterruptedException {
t1 = new Client1();
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Client frame = new Client();
Client1 frame = new Client1();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
@ -56,7 +63,6 @@ public class Client extends JFrame {
}
});
try {
start();
} catch (ClassNotFoundException e) {
@ -68,8 +74,12 @@ public class Client extends JFrame {
}
}
public Client() {
/*
In der Methode Client1() wird das GUI
und die Befehle die durch einen Click des
Button's ausgelöst werden festgelegt
*/
public Client1() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
@ -79,99 +89,224 @@ public class Client extends JFrame {
txtMessage = new JTextField();
txtMessage.setText("Message");
txtMessage.setBounds(117, 29, 218, 20);
txtMessage.setBounds(20, 230, 218, 20);
contentPane.add(txtMessage);
txtMessage.setColumns(10);
txtUsername = new JTextField();
txtUsername.setText("Username");
txtUsername.setBounds(21, 29, 86, 20);
txtUsername.setBounds(20, 11, 86, 20);
contentPane.add(txtUsername);
txtUsername.setColumns(10);
/**
* Der Button "Send" nimmt die aktuelle Nachricht, welche im Textfeld
* "message" geschrieben wurde und schreibt diese als ein Message-Objekt
* in den Output-Stream an den Server, falls die Socket bereits
* verbunden ist.
*
* Falls die Nachricht "exit" sein sollte, wird die GUI beendet.
*/
JButton btnSend = new JButton("Send");
btnSend.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (verbunden) {
String themessage = txtMessage.getText();
String theusername = txtUsername.getText();
tosend = new Message(theusername, themessage);
i = 1;
temp = new Message(theusername, themessage);
System.out.println("Button pressed");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try {
try {
oboust.writeObject(tosend);
oboust.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (Exception k) {
print("KEINE VERBINDUNG");
}
if (temp.getMessage().equals("exit")) {
System.exit(0);
}
txtMessage.setText("");
}
}
});
btnSend.setBounds(345, 28, 79, 23);
btnSend.setBounds(264, 229, 79, 23);
contentPane.add(btnSend);
JTextArea textArea = new JTextArea(currentText);
/**
* Hier wird die textArea, auf welcher der Text ausgegeben wird
* initialisiert
*
*/
textArea = new JTextArea(currentText);
textArea.setLineWrap(true);
textArea.setForeground(Color.WHITE);
textArea.setForeground(Color.BLACK);
textArea.setBackground(Color.LIGHT_GRAY);
textArea.setBounds(20, 60, 323, 176);
textArea.setBounds(20, 42, 323, 176);
contentPane.add(textArea);
/**
* Der Start Button sorgt sorgt dafür, dass der Username festgesetzt
* wird, wodurch er nicht veränderlich ist. Außerdem wird die globale
* Variabel j von 0 auf 1 gestzt, wodurch die start-Methode weiß, dass
* sie eine Verbindung aufbauen soll.
*
*/
JButton btnStart = new JButton("Start");
btnStart.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
txtUsername.setEditable(false);
txtUsername.setEnabled(false);
verbunden = true;
}
});
btnStart.setBounds(116, 10, 89, 23);
contentPane.add(btnStart);
}
public static void print(JTextArea textArea, String asd){
currentText = asd + "\n" + currentText;
/**
* In der Print-Methode wird der neue Text (also eine neue Nachricht) auf
* die textArea abgebildet.
*/
public static void print(String neuerText) {
currentText = neuerText + "\n" + currentText;
textArea.setText(currentText);
}
public static void start() throws IOException, ClassNotFoundException{
/**
* Die start-Methode wartet, bis die Variable verbunden durch Klicken des
* Start Buttons auf true gesetzt wird, erst dann beginnt die eigentliche
* Methode.
*
* Es wird dann eine Verbindung zum Socket über den Port 1236 aufgebaut.
* Sollte dies nicht Möglich sein, wird die Fehlermeldung in der GUI
* ausgegeben, sodass der Nutzer weiß, dass keine Vebrindung möglich ist.
*
* Es wird im Sekundentakt nach einer neuen Verbindung gesucht.
*
*/
public static void start() throws IOException, ClassNotFoundException, InterruptedException {
while (!verbunden) {
Thread.sleep(100);
}
txtUsername.setEnabled(false);
Scanner scan = new Scanner(System.in);
JTextArea textArea = new JTextArea(currentText);
textArea.setLineWrap(true);
textArea.setForeground(Color.WHITE);
textArea.setBackground(Color.BLACK);
textArea.setBounds(20, 60, 323, 176);
contentPane.add(textArea);
try {
socket = new Socket("localhost", 1236);
oboust = new ObjectOutputStream(socket.getOutputStream());
obinstr = new ObjectInputStream(socket.getInputStream());
Object erhalten = null;
Message message = new Message("leer", "leer");
while(!message.getMessage().equals("exit")){
System.out.println("While");
print("VERBINDUNG HERGESTELLT");
} catch (Exception KeineSocket) {
print("SERVER ANTWORTET NICHT");
try {
erhalten = obinstr.readObject(); //Bleibt hier stehen, bis ein neues Object reinkommt
System.out.println("Nachricht erhalten");
message = (Message)erhalten;
System.out.println(message.getMessage());
String Ausgeben = "[" + message.getUsername() + "] " + message.getMessage();
print(textArea, Ausgeben);
System.out.println("[" + message.getUsername() + "] " + message.getMessage());
oboust.flush();
}catch(Exception f){
try {
Thread.sleep(1000);
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
anzahlRekursionen++;
if (anzahlRekursionen == 10) {
print("KEINE ANTWORT, CLIENT WIRD BEENDET");
Thread.sleep(10000);
System.exit(0);
}
start();
System.exit(0);
}
Object erhalten = null;
Message message = new Message("leer", "leer");
/**
* Die While Schleife ist der Listener, dieser wartet auf Nachrichten
* aus dem Server und gibt diese dann aus.
*
* Im Falle eines Verindungsabbruches versucht er es 5 mal im Abstand
* von 2 Sekunden nochmal eine Nachricht zu senden und ruft dann wieder
* die start() Methode auf. wodurch die Verbindung nochmal neu
* hergestellt wird.
*
* Die While-Schleife wird abgebrochen, sobald die Nachricht, welche der
* Benutzer über das GUI sendet "exit" lautet.
*
*/
while (!temp.getMessage().equals("exit")) {
//System.out.println("WHILE");
try {
//System.out.println("hile4");
System.out.println("Nachricht erhalten");
erhalten = obinstr.readObject(); //Bleibt hier stehen, bis ein neues Object reinkommt
message = (Message) erhalten;
System.out.println("[" + message.getUsername() + "] " + message.getMessage());
String Ausgeben = message.getTime() + " [" + message.getUsername() + "] " + message.getMessage();
print(Ausgeben);
//System.out.println("[CLIENT] NACHRICHT ERHALTEN");
oboust.flush();
} catch (SocketException h) {
System.out.println(h);
print("VERBINDUNGSABBRUCH");
anzahlVersuche++;
Thread.sleep(2000);
if (anzahlVersuche == 5) {
anzahlVersuche = 0;
anzahlRekursionen++;
if (anzahlRekursionen == 10) {
print("KEINE ANTWORT, CLIENT WIRD BEENDET");
Thread.sleep(10000);
System.exit(0);
}
start();
System.exit(0);
}
} catch (Exception f) {
Thread.sleep(1000);
}
}
/**
* Nach dem Abbruch der While Schleife, was nur bei der Nachricht exit
* passiert, schließt der Client den ObjectOutputstream,
* Objectinputstream und den Socket und beendet dann das Programm
*/
oboust.close();
obinstr.close();
socket.close();
}
System.exit(0);
}
}

View file

@ -20,14 +20,12 @@ import java.awt.event.ActionEvent;
/**
* Hauptklasse des Clients
*
* @version 0.1.3
* @author berdan
*/
public class Client1 extends JFrame {
/*
Hier werden Objekte und Variablen deklariert, damit diese
in allen Methoden genutzt werden können.
@ -52,7 +50,6 @@ public class Client1 extends JFrame {
In der main Methode wird das GUI erstellt und die
start() Methode aufgerufen.
*/
public static void main(String[] args) throws InterruptedException {
t1 = new Client1();
EventQueue.invokeLater(new Runnable() {
@ -66,7 +63,6 @@ public class Client1 extends JFrame {
}
});
try {
start();
} catch (ClassNotFoundException e) {
@ -78,13 +74,11 @@ public class Client1 extends JFrame {
}
}
/*
In der Methode Client1() wird das GUI
und die Befehle die durch einen Click des
Button's ausgelöst werden festgelegt
*/
public Client1() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
@ -105,17 +99,14 @@ public class Client1 extends JFrame {
contentPane.add(txtUsername);
txtUsername.setColumns(10);
/*
Der Button "Send" nimmt die aktuelle Nachricht,
welche im Textfeld "message" geschrieben wurde und
schreibt diese als ein Message-Objekt in den Output-Stream
an den Server, falls die Socket bereits verbunden ist.
Falls die Nachricht "exit" sein sollte, wird
die GUI beendet.
/**
* Der Button "Send" nimmt die aktuelle Nachricht, welche im Textfeld
* "message" geschrieben wurde und schreibt diese als ein Message-Objekt
* in den Output-Stream an den Server, falls die Socket bereits
* verbunden ist.
*
* Falls die Nachricht "exit" sein sollte, wird die GUI beendet.
*/
JButton btnSend = new JButton("Send");
btnSend.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
@ -158,10 +149,10 @@ public class Client1 extends JFrame {
btnSend.setBounds(264, 229, 79, 23);
contentPane.add(btnSend);
/*
Hier wird die textArea, auf welcher der Text ausgegeben wird
initialisiert
/**
* Hier wird die textArea, auf welcher der Text ausgegeben wird
* initialisiert
*
*/
textArea = new JTextArea(currentText);
textArea.setLineWrap(true);
@ -170,15 +161,13 @@ public class Client1 extends JFrame {
textArea.setBounds(20, 42, 323, 176);
contentPane.add(textArea);
/*
Der Start Button sorgt sorgt dafür, dass der Username
festgesetzt wird, wodurch er nicht veränderlich ist.
Außerdem wird die globale Variabel j von 0 auf 1 gestzt,
wodurch die start-Methode weiß, dass sie eine Verbindung
aufbauen soll.
/**
* Der Start Button sorgt sorgt dafür, dass der Username festgesetzt
* wird, wodurch er nicht veränderlich ist. Außerdem wird die globale
* Variabel j von 0 auf 1 gestzt, wodurch die start-Methode weiß, dass
* sie eine Verbindung aufbauen soll.
*
*/
JButton btnStart = new JButton("Start");
btnStart.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
@ -192,36 +181,30 @@ public class Client1 extends JFrame {
btnStart.setBounds(116, 10, 89, 23);
contentPane.add(btnStart);
}
/*
In der Print-Methode wird der neue Text (also eine neue Nachricht)
auf die textArea abgebildet.
/**
* In der Print-Methode wird der neue Text (also eine neue Nachricht) auf
* die textArea abgebildet.
*/
public static void print(String neuerText) {
currentText = neuerText + "\n" + currentText;
textArea.setText(currentText);
}
/*
Die start-Methode wartet, bis die Variable verbunden durch Klicken
des Start Buttons auf true gesetzt wird, erst dann beginnt die
eigentliche Methode.
Es wird dann eine Verbindung zum Socket über den Port
1236 aufgebaut. Sollte dies nicht Möglich sein, wird die
Fehlermeldung in der GUI ausgegeben, sodass der Nutzer weiß,
dass keine Vebrindung möglich ist.
Es wird im Sekundentakt nach einer neuen Verbindung gesucht.
/**
* Die start-Methode wartet, bis die Variable verbunden durch Klicken des
* Start Buttons auf true gesetzt wird, erst dann beginnt die eigentliche
* Methode.
*
* Es wird dann eine Verbindung zum Socket über den Port 1236 aufgebaut.
* Sollte dies nicht Möglich sein, wird die Fehlermeldung in der GUI
* ausgegeben, sodass der Nutzer weiß, dass keine Vebrindung möglich ist.
*
* Es wird im Sekundentakt nach einer neuen Verbindung gesucht.
*
*/
public static void start() throws IOException, ClassNotFoundException, InterruptedException {
while (!verbunden) {
@ -255,27 +238,22 @@ public class Client1 extends JFrame {
}
Object erhalten = null;
Message message = new Message("leer", "leer");
/*
Die While Schleife ist der Listener,
dieser wartet auf Nachrichten aus dem Server und
gibt diese dann aus.
Im Falle eines Verindungsabbruches versucht er
es 5 mal im Abstand von 2 Sekunden nochmal eine Nachricht
zu senden und ruft dann wieder die start() Methode auf.
wodurch die Verbindung nochmal neu hergestellt wird.
Die While-Schleife wird abgebrochen, sobald die Nachricht,
welche der Benutzer über das GUI sendet "exit" lautet.
/**
* Die While Schleife ist der Listener, dieser wartet auf Nachrichten
* aus dem Server und gibt diese dann aus.
*
* Im Falle eines Verindungsabbruches versucht er es 5 mal im Abstand
* von 2 Sekunden nochmal eine Nachricht zu senden und ruft dann wieder
* die start() Methode auf. wodurch die Verbindung nochmal neu
* hergestellt wird.
*
* Die While-Schleife wird abgebrochen, sobald die Nachricht, welche der
* Benutzer über das GUI sendet "exit" lautet.
*
*/
while (!temp.getMessage().equals("exit")) {
//System.out.println("WHILE");
try {
@ -291,16 +269,13 @@ public class Client1 extends JFrame {
oboust.flush();
}
catch(SocketException h){
} catch (SocketException h) {
System.out.println(h);
print("VERBINDUNGSABBRUCH");
anzahlVersuche++;
Thread.sleep(2000);
if (anzahlVersuche == 5) {
anzahlVersuche = 0;
anzahlRekursionen++;
@ -312,32 +287,26 @@ public class Client1 extends JFrame {
}
start();
System.exit(0);
}
}
catch(Exception f){
} catch (Exception f) {
Thread.sleep(1000);
}
}
/*
Nach dem Abbruch der While Schleife, was nur bei der
Nachricht exit passiert, schließt der Client
den ObjectOutputstream, Objectinputstream und den Socket
und beendet dann das Programm
/**
* Nach dem Abbruch der While Schleife, was nur bei der Nachricht exit
* passiert, schließt der Client den ObjectOutputstream,
* Objectinputstream und den Socket und beendet dann das Programm
*/
oboust.close();
obinstr.close();
socket.close();
System.exit(0);
}
}

View file

@ -25,15 +25,36 @@ import java.util.logging.Logger;
import utils.Message;
/**
* Diese Klasse stellt einen Thread dar, der auf Nachrichten eines Clients lauscht und diese dann weiter gibt.
* Diese Klasse stellt einen Thread dar, der auf Nachrichten eines Clients
* lauscht und diese dann weiter gibt.
*
* @version 1.0.0
* @author eichehome
*/
public class ClientReciveMessageThread extends Thread {
/**
* Attribut, welches einen Zeiger auf das zentrale Verzeichnis aller
* verbundenen Clients enthält.
*/
private ClientStore clientStore;
/**
* Attribut, welches den von Client kommenden Stream repräsentiert.
*/
private final ObjectInputStream in;
/**
* Konstruktor
*
* @param in Stream, in dem die Nachrichten eines Clients ankommen.
* @param clientStore Zeiger auf das zentrale Verzeichnis der Clients, um
* alle benachrichtigen zu können.
*/
public ClientReciveMessageThread(ObjectInputStream in, ClientStore clientStore) {
this.in = in;
this.clientStore = clientStore;
}
/**
* Hauptmethode des Threads, in der alles abläuft.
*/
@ -43,7 +64,7 @@ public class ClientReciveMessageThread extends Thread {
while (continueLoop) {
try {
Message empfangen = null;
while ((empfangen = (Message) this.in.readObject()) != null) {
while ((empfangen = (Message) this.in.readObject()) != null) {//Der Thread pleibt hier stehen bis er eine Nachricht vom Client erhält.
Logger.getLogger(ClientReciveMessageThread.class.getName()).log(Level.INFO, String.format("Reciveing Thread %d: Time: %s Client: %s Message: %s", this.getId(), empfangen.getTime(), empfangen.getUsername(), empfangen.getMessage()));
for (ObjectOutputStream stream : clientStore.getAllOutputStreams()) {
stream.writeObject(empfangen);
@ -53,7 +74,7 @@ public class ClientReciveMessageThread extends Thread {
}
} catch (ClassNotFoundException ex) {
Logger.getLogger(ClientReciveMessageThread.class.getName()).log(Level.SEVERE, String.format("Reciveing Thread %d: Fehler: %s", this.getId(), ex));
} catch (EOFException ex) {
} catch (EOFException ex) {//Diese Exception zeigt, dass sich die Verbundung zum Client geschlossen hat. Die Aufräumarbeiten übernimmt der Sending Thread diese Clients.
Logger.getLogger(ClientReciveMessageThread.class.getName()).log(Level.INFO, String.format("Reciveing Thread %d: Socket wurde beendet", this.getId()));
continueLoop = false;
} catch (IOException ex) {
@ -63,13 +84,4 @@ public class ClientReciveMessageThread extends Thread {
}
}
/**
* Konstruktor
* @param in Stream, in dem die Nachrichten eines Clients ankommen.
* @param clientStore Zeiger auf das zentrale Verzeichnis der Clients, um alle benachrichtigen zu können.
*/
public ClientReciveMessageThread(ObjectInputStream in, ClientStore clientStore) {
this.in = in;
this.clientStore = clientStore;
}
}

View file

@ -25,16 +25,46 @@ import java.util.logging.Logger;
import utils.Message;
/**
* Diese Klasse stellt einen Thread dar, die Nachrichten, die er in einem Stream erhällt an einen Client weiterleitet.
* Diese Klasse stellt einen Thread dar, die Nachrichten, die er in einem Stream
* erhällt an einen Client weiterleitet.
*
* @version 1.0.0
* @author eichehome
*/
public class ClientPushMessageThread extends Thread {
public class ClientSendMessageThread extends Thread {
/**
* Attribut, welches den Stream enthält, in dem die Nachrichten an den
* Client geschickt werden.
*/
private final ObjectOutputStream out;
/**
* Attribut, welches den Stream enthält, in dem die Nachrichten ankommen,
* die an den Client geschickt werden sollen.
*/
private final ObjectInputStream pipedObjectInputStream;
/**
* Attribut, welches einen Zeiger auf das zentrale Verzeichnis aller
* verbundenen Clients enthält.
*/
private ClientStore clientStore;
/**
* Konstruktor
*
* @param out Stream, in dem der Thread die Nachrichten an den Client
* schickt.
* @param pipedObjectInputStream Stream, in dem der Thread die Nachrichten
* von anderen Threads erhält.
* @param clientStore Zeiger auf das zentrale Verzeichnis der Clients, um
* sich dort austragen zu können.
*/
public ClientSendMessageThread(ObjectOutputStream out, ObjectInputStream pipedObjectInputStream, ClientStore clientStore) {
this.out = out;
this.pipedObjectInputStream = pipedObjectInputStream;
this.clientStore = clientStore;
}
/**
* Hauptmethode der Threads, in der alles abläuft.
*/
@ -43,36 +73,25 @@ public class ClientPushMessageThread extends Thread {
while (continueLoop) {
try {
Message empfangen = null;
while ((empfangen = (Message) this.pipedObjectInputStream.readObject()) != null) {
while ((empfangen = (Message) this.pipedObjectInputStream.readObject()) != null) {//Hier bleibt dieser Thread stehen bis er eine Nchricht erhält, die er an den Client weiterleiten soll.
this.out.writeObject(empfangen);
this.out.flush();
Logger.getLogger(ClientPushMessageThread.class.getName()).log(Level.INFO, String.format("Pushing Thread %d: Nachricht weitergegeben", this.getId()));
Logger.getLogger(ClientSendMessageThread.class.getName()).log(Level.INFO, String.format("Sending Thread %d: Nachricht weitergegeben", this.getId()));
}
} catch (ClassNotFoundException ex) {
Logger.getLogger(ClientPushMessageThread.class.getName()).log(Level.SEVERE, String.format("Pushing Thread %d: Fehler: %s", this.getId(), ex));
Logger.getLogger(ClientSendMessageThread.class.getName()).log(Level.SEVERE, String.format("Sending Thread %d: Fehler: %s", this.getId(), ex));
} catch (EOFException ex) {
Logger.getLogger(ClientPushMessageThread.class.getName()).log(Level.SEVERE, String.format("Pushing Thread %d: Fehler: %s", this.getId(), ex));
Logger.getLogger(ClientSendMessageThread.class.getName()).log(Level.SEVERE, String.format("Sending Thread %d: Fehler: %s", this.getId(), ex));
continueLoop = false;
clientStore.close(this);
clientStore.removeClient(this);
} catch (IOException ex) {
Logger.getLogger(ClientPushMessageThread.class.getName()).log(Level.INFO, String.format("Pushing Thread %d: Pipe wurde beendet", this.getId()));
clientStore.removeClient(this);
this.clientStore.close(this);
this.clientStore.removeClient(this);
} catch (IOException ex) {//Diese Exeption zeigt, dass sich der Stream zum Client geschlossen hat und deshalb Aufräumarbeiten angebracht sind.
Logger.getLogger(ClientSendMessageThread.class.getName()).log(Level.INFO, String.format("Sending Thread %d: Pipe wurde beendet", this.getId()));
this.clientStore.close(this);
this.clientStore.removeClient(this);
continueLoop = false;
}
}
}
/**
* Konstruktor
* @param out Stream, in dem der Thread die Nachrichten an den Client schickt.
* @param pipedObjectInputStream Stream, in dem der Thread die Nachrichten von anderen Threads erhält.
* @param clientStore Zeiger auf das zentrale Verzeichnis der Clients, um sich dort austragen zu können.
*/
public ClientPushMessageThread(ObjectOutputStream out, ObjectInputStream pipedObjectInputStream, ClientStore clientStore) {
this.out = out;
this.pipedObjectInputStream = pipedObjectInputStream;
this.clientStore = clientStore;
}
}

View file

@ -23,23 +23,29 @@ import java.util.logging.Level;
import utils.Client;
/**
* Diese Klasse Stellt das zentrale Verzeichniss aller Clients dar.
* Diese Klasse stellt das zentrale Verzeichniss aller Clients dar.
*
* @version 1.0.0
* @author eichehome
*/
public class ClientStore {
/**
* Attribut, welches ein Array aller verbundenen Clients enthält.
*/
private Client[] clients = null;
/**
* Diese Funktion fügt einen Client dem Verzeichniss aller Clients hinzu, die Verbunden sind.
* Funktion, welche einen Client dem Verzeichniss aller verbundenen Clients
* hinzufügt.
*
* @param newClient Der neue Client, der hinzugefügt werden soll.
*/
public void addClient(Client newClient) {
if (this.clients != null) {
Client[] temp = new Client[this.clients.length + 1];
System.arraycopy(clients, 0, temp, 0, clients.length);
temp[temp.length - 1] = newClient;
temp[temp.length - 1] = newClient;//Letzter Eintrag ist der neue Client.
this.clients = temp;
} else {
Client[] temp = new Client[1];
@ -50,28 +56,32 @@ public class ClientStore {
}
/**
* Dies Funktion entfernt einen Client aus dem Verzeichnis aller verbundenen Clients.
* @param pusher Der Pusher-Thread des Clients, welcher aus dem Verzeichnis entfernt werden soll.
* Funktion, welche einen Client aus dem Verzeichnis aller verbundenen
* Clients entfernt.
*
* @param sender Der Pusher-Thread des Clients, welcher aus dem Verzeichnis
* entfernt werden soll.
* @return Gibt die zu dem Client gehörenden Streams und Threads zurück.
* @throws IllegalArgumentException Falls der Thread nicht existiert oder keine Clients vorhanden sind, wird eine Exeption mit der passenden Fehlermeldung geworfen.
* @throws IllegalArgumentException Falls der Thread nicht existiert oder
* keine Clients vorhanden sind, wird eine Exeption mit der passenden
* Fehlermeldung geworfen.
*/
public Client removeClient(Thread pusher) throws IllegalArgumentException {
public Client removeClient(Thread sender) {
if (this.clients != null) {
int index = -1;
//Suche nach dem Element in dem Array
for (int i = 0; i < this.clients.length; i++) {
if (this.clients[i].getPusher().equals(pusher)) {
if (this.clients[i].getSender().equals(sender)) {
index = i;
break;
}
}
if (index != -1) {
Client[] temp = new Client[this.clients.length - 1];
for (int i = 0; i < index; i++) {
temp[i] = this.clients[i];
}
for (int i = (index + 1); i < this.clients.length; i++) {
temp[i - 1] = this.clients[i];
}
//Teil des Arrays vor dem Index des zu entfernenden Elements kopieren.
System.arraycopy(this.clients, 0, temp, 0, index);
//Teil des Arrays nach dem Index des zu entfernenden Elements 1 Index nach vorne kopieren.
System.arraycopy(this.clients, (index + 1), temp, index, (this.clients.length - (index + 1)));
Client result = this.clients[index];
this.clients = temp;
Logger.getLogger(ClientStore.class.getName()).log(Level.INFO, "ClientStore: Client gelöscht");
@ -85,7 +95,9 @@ public class ClientStore {
}
/**
* Diese Funktion gibt alle Streams zu den Clients zurück, die derzeit Verbunden sind.
* Funktion, welche alle Streams zu den Clients, die derzeit Verbunden sind,
* zurückgibt.
*
* @return Ein Array aus allen Streams
*/
public ObjectOutputStream[] getAllOutputStreams() {
@ -98,15 +110,18 @@ public class ClientStore {
}
/**
* Schließt den zu einem Thread gehörenden OutputStream
* @param thread Der Thread, dessen OutputStream geschlossen werden soll
* @throws IllegalArgumentException Falls der Thread nicht existiert oder keine Clients vorhanden sind, wird eine Exeption mit der passenden Fehlermeldung geworfen.
* Funktion, die den zu einem Thread gehörenden OutputStream schließt.
*
* @param sender Der Thread, dessen OutputStream geschlossen werden soll
* @throws IllegalArgumentException Falls der Thread nicht existiert oder
* keine Clients vorhanden sind, wird eine Exeption mit der passenden
* Fehlermeldung geworfen.
*/
public void close(Thread thread) throws IllegalArgumentException{
public void close(Thread sender) {
if (this.clients != null) {
int index = -1;
for (int i = 0; i < this.clients.length; i++) {
if (clients[i].getPusher().equals(thread)) {
if (this.clients[i].getSender().equals(sender)) {
index = i;
}
}

View file

@ -20,7 +20,8 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.net.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import utils.Client;
@ -28,13 +29,13 @@ import utils.Client;
/**
* Hauptklasse des Servers
*
* @version 0.0.1
* @version 1.0.0
* @author eichehome
*/
public class MainServer {
/**
* Einstiegsklasse des Servers. Diese wartet auf Anfragen der Clients und erstellt dann die nötigen Resourcen (Streams und Threads).
* Einstiegsfunktion des Servers, welche auf Anfragen der Clients wartet und dann die nötigen Resourcen (Streams und Threads) erstellt.
* @param args the command line arguments
*/
public static void main(String[] args) {
@ -42,7 +43,7 @@ public class MainServer {
ClientStore clientStore = new ClientStore();
while (true) {
Logger.getLogger(MainServer.class.getName()).log(Level.INFO, String.format("Main: Warte auf Clients"));
Socket client = serverSocket.accept();
Socket client = serverSocket.accept();//Hier bleibt der server stehen und geht erst weiter wenn ein Client sich verbinden will.
Logger.getLogger(MainServer.class.getName()).log(Level.INFO, String.format("Main: Client verbunden"));
PipedOutputStream pipedOutputStream = new PipedOutputStream();
@ -57,16 +58,16 @@ public class MainServer {
Logger.getLogger(MainServer.class.getName()).log(Level.INFO, String.format("Main: Streams erstellt"));
Thread threadRecive = new ClientReciveMessageThread(in, clientStore);
Thread threadPush = new ClientPushMessageThread(out, pipedObjectInputStream, clientStore);
Thread threadSend = new ClientSendMessageThread(out, pipedObjectInputStream, clientStore);
Logger.getLogger(MainServer.class.getName()).log(Level.INFO, String.format("Main: Threads erstellt"));
threadPush.start();
threadSend.start();
threadRecive.start();
Logger.getLogger(MainServer.class.getName()).log(Level.INFO, String.format("Main: Threads gestartet"));
clientStore.addClient(new Client(pipedObjectOutputStream, threadPush, threadRecive));
clientStore.addClient(new Client(pipedObjectOutputStream, threadSend, threadRecive));
}
} catch (Exception ex) {

View file

@ -18,44 +18,64 @@ package utils;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.logging.Logger;
import java.util.logging.Level;
/**
* Dies Klasse stellt einen Client mit seinen Streams dar.
*
* @version 1.0.0
* @author eichehome
*/
public class Client {
/**
* Attribut, welches den Stream enthält, in dem Nachrichten an den Thread
* geschickt werden können, der diese an den Client weiterleitet.
*/
private final ObjectOutputStream out;
private final Thread pusher;
/**
* Attribut, welches einen Zeiger auf den Thread enthält, welcher
* Nachrichten an den Client schickt.
*/
private final Thread sender;
/**
* Attribut, welches einen Zeiger auf den Thread enthält, welcher
* Nachrichten von dem Client empfängt.
*/
private final Thread reciver;
/**
* Konstruktor
*
* @param out Stream, um diesem Client Nachrichten schicken zu können.
* @param pusher Zeiger auf den Thread, der die Nachrichten an den Client sendet.
* @param reciver Zeiger auf den Thread, der die Nachrichten eines Clients empfängt.
* @param sender Zeiger auf den Thread, der die Nachrichten an den Client
* sendet.
* @param reciver Zeiger auf den Thread, der die Nachrichten eines Clients
* empfängt.
*/
public Client(ObjectOutputStream out, Thread pusher, Thread reciver) {
public Client(ObjectOutputStream out, Thread sender, Thread reciver) {
this.out = out;
this.pusher = pusher;
this.sender = sender;
this.reciver = reciver;
}
/**
* Schreibe eine Nachricht in den OutputStream dieses Clients.
*
* @param message Die zu verschickende Nachricht.
*/
public void writeMessage(Message message) {
try {
this.out.writeObject(message);
} catch (IOException ex) {
System.err.println("Cliet: Fehler: " + ex);
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, String.format("Client: Fehler: %s", ex));
}
}
/**
* Getter für den OutputStream diese Clients
*
* @return Zeiger auf den Stream.
*/
public ObjectOutputStream getOutputStream() {
@ -64,14 +84,16 @@ public class Client {
/**
* Getter für den Thread, der Nachrichten an diesen Client sendet.
*
* @return Zeiger auf den Thread.
*/
public Thread getPusher() {
return this.pusher;
public Thread getSender() {
return this.sender;
}
/**
* Getter für den Thread, der Nchrichten an diesen Client sendet.
*
* @return Zeiger auf den Thread.
*/
public Thread getReciver() {