This commit is contained in:
BerdanInformatik123 2021-05-16 21:02:05 +02:00
commit 6275efdcb3
9 changed files with 487 additions and 295 deletions

View file

@ -1,15 +1,10 @@
package client; package client;
import java.awt.BorderLayout;
import java.awt.EventQueue; import java.awt.EventQueue;
import java.awt.TextArea;
import javax.swing.JFrame; import javax.swing.JFrame;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
import utils.Message; import utils.Message;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JTextArea; import javax.swing.JTextArea;
@ -19,36 +14,48 @@ import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.net.Socket; import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner; import java.util.Scanner;
import java.awt.event.ActionEvent; 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; private static JPanel contentPane;
JTextField txtMessage; JTextField txtMessage;
private JTextField txtUsername; private static JTextField txtUsername;
public static String currentText = " "; public static String currentText = " ";
public static int i = 0; public static int i = 0;
public static Object tosend = new Message("Leer", "Leer"); public static Object tosend = new Message("Leer", "Leer");
public static Client t1; public static Client1 t1;
public static Socket socket; public static Socket socket;
public static ObjectInputStream obinstr; public static ObjectInputStream obinstr;
public static ObjectOutputStream oboust; 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 In der main Methode wird das GUI erstellt und die
* @version 0.0.2 start() Methode aufgerufen.
* @author berdan
*/ */
public static void main(String[] args) throws InterruptedException {
t1 = new Client1();
public static void main(String[] args) {
t1 = new Client();
EventQueue.invokeLater(new Runnable() { EventQueue.invokeLater(new Runnable() {
public void run() { public void run() {
try { try {
Client frame = new Client(); Client1 frame = new Client1();
frame.setVisible(true); frame.setVisible(true);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -56,7 +63,6 @@ public class Client extends JFrame {
} }
}); });
try { try {
start(); start();
} catch (ClassNotFoundException e) { } 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); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300); setBounds(100, 100, 450, 300);
contentPane = new JPanel(); contentPane = new JPanel();
@ -79,99 +89,224 @@ public class Client extends JFrame {
txtMessage = new JTextField(); txtMessage = new JTextField();
txtMessage.setText("Message"); txtMessage.setText("Message");
txtMessage.setBounds(117, 29, 218, 20); txtMessage.setBounds(20, 230, 218, 20);
contentPane.add(txtMessage); contentPane.add(txtMessage);
txtMessage.setColumns(10); txtMessage.setColumns(10);
txtUsername = new JTextField(); txtUsername = new JTextField();
txtUsername.setText("Username"); txtUsername.setText("Username");
txtUsername.setBounds(21, 29, 86, 20); txtUsername.setBounds(20, 11, 86, 20);
contentPane.add(txtUsername); contentPane.add(txtUsername);
txtUsername.setColumns(10); 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"); JButton btnSend = new JButton("Send");
btnSend.addActionListener(new ActionListener() { btnSend.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) { public void actionPerformed(ActionEvent arg0) {
if (verbunden) {
String themessage = txtMessage.getText(); String themessage = txtMessage.getText();
String theusername = txtUsername.getText(); String theusername = txtUsername.getText();
tosend = new Message(theusername, themessage); tosend = new Message(theusername, themessage);
i = 1; i = 1;
temp = new Message(theusername, themessage);
System.out.println("Button pressed"); System.out.println("Button pressed");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try {
try { try {
oboust.writeObject(tosend); oboust.writeObject(tosend);
oboust.flush(); oboust.flush();
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace(); 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); 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.setLineWrap(true);
textArea.setForeground(Color.WHITE); textArea.setForeground(Color.BLACK);
textArea.setBackground(Color.LIGHT_GRAY); textArea.setBackground(Color.LIGHT_GRAY);
textArea.setBounds(20, 60, 323, 176); textArea.setBounds(20, 42, 323, 176);
contentPane.add(textArea); 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); 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); Scanner scan = new Scanner(System.in);
JTextArea textArea = new JTextArea(currentText); try {
textArea.setLineWrap(true); socket = new Socket("localhost", 1236);
textArea.setForeground(Color.WHITE);
textArea.setBackground(Color.BLACK);
textArea.setBounds(20, 60, 323, 176);
contentPane.add(textArea);
socket = new Socket( "localhost", 1236 );
oboust = new ObjectOutputStream(socket.getOutputStream()); oboust = new ObjectOutputStream(socket.getOutputStream());
obinstr = new ObjectInputStream(socket.getInputStream()); obinstr = new ObjectInputStream(socket.getInputStream());
print("VERBINDUNG HERGESTELLT");
Object erhalten = null; } catch (Exception KeineSocket) {
Message message = new Message("leer", "leer"); print("SERVER ANTWORTET NICHT");
while(!message.getMessage().equals("exit")){
System.out.println("While");
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 { try {
Thread.sleep(1000); Thread.sleep(5000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); 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(); oboust.close();
obinstr.close(); obinstr.close();
socket.close(); socket.close();
System.exit(0);
} }
} }

View file

@ -25,15 +25,36 @@ import java.util.logging.Logger;
import utils.Message; 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 * @author eichehome
*/ */
public class ClientReciveMessageThread extends Thread { public class ClientReciveMessageThread extends Thread {
/**
* Attribut, welches einen Zeiger auf das zentrale Verzeichnis aller
* verbundenen Clients enthält.
*/
private ClientStore clientStore; private ClientStore clientStore;
/**
* Attribut, welches den von Client kommenden Stream repräsentiert.
*/
private final ObjectInputStream in; 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. * Hauptmethode des Threads, in der alles abläuft.
*/ */
@ -43,7 +64,7 @@ public class ClientReciveMessageThread extends Thread {
while (continueLoop) { while (continueLoop) {
try { try {
Message empfangen = null; 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())); 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()) { for (ObjectOutputStream stream : clientStore.getAllOutputStreams()) {
stream.writeObject(empfangen); stream.writeObject(empfangen);
@ -53,7 +74,7 @@ public class ClientReciveMessageThread extends Thread {
} }
} catch (ClassNotFoundException ex) { } catch (ClassNotFoundException ex) {
Logger.getLogger(ClientReciveMessageThread.class.getName()).log(Level.SEVERE, String.format("Reciveing Thread %d: Fehler: %s", this.getId(), 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())); Logger.getLogger(ClientReciveMessageThread.class.getName()).log(Level.INFO, String.format("Reciveing Thread %d: Socket wurde beendet", this.getId()));
continueLoop = false; continueLoop = false;
} catch (IOException ex) { } 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,54 +25,73 @@ import java.util.logging.Logger;
import utils.Message; 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 * @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; 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; private final ObjectInputStream pipedObjectInputStream;
/**
* Attribut, welches einen Zeiger auf das zentrale Verzeichnis aller
* verbundenen Clients enthält.
*/
private ClientStore clientStore; private ClientStore clientStore;
/** /**
* Haupt methode der Threads, in der alles abläuft. * 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.
*/ */
public void run() { public void run() {
boolean continueLoop = true; boolean continueLoop = true;
while (continueLoop) { while (continueLoop) {
try { try {
Message empfangen = null; 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.writeObject(empfangen);
this.out.flush(); 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) { } 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) { } 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; continueLoop = false;
clientStore.close(this); this.clientStore.close(this);
clientStore.removeClient(this); this.clientStore.removeClient(this);
} catch (IOException ex) { } catch (IOException ex) {//Diese Exeption zeigt, dass sich der Stream zum Client geschlossen hat und deshalb Aufräumarbeiten angebracht sind.
Logger.getLogger(ClientPushMessageThread.class.getName()).log(Level.INFO, String.format("Pushing Thread %d: Pipe wurde beendet", this.getId())); Logger.getLogger(ClientSendMessageThread.class.getName()).log(Level.INFO, String.format("Sending Thread %d: Pipe wurde beendet", this.getId()));
clientStore.removeClient(this); this.clientStore.close(this);
this.clientStore.removeClient(this);
continueLoop = false; 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; 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 * @author eichehome
*/ */
public class ClientStore { public class ClientStore {
/**
* Attribut, welches ein Array aller verbundenen Clients enthält.
*/
private Client[] clients = null; 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. * @param newClient Der neue Client, der hinzugefügt werden soll.
*/ */
public void addClient(Client newClient) { public void addClient(Client newClient) {
if (this.clients != null) { if (this.clients != null) {
Client[] temp = new Client[this.clients.length + 1]; Client[] temp = new Client[this.clients.length + 1];
System.arraycopy(clients, 0, temp, 0, clients.length); 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; this.clients = temp;
} else { } else {
Client[] temp = new Client[1]; Client[] temp = new Client[1];
@ -50,28 +56,32 @@ public class ClientStore {
} }
/** /**
* Dies Funktion entfernt einen Client aus dem Verzeichnis aller verbundenen Clients. * Funktion, welche einen Client aus dem Verzeichnis aller verbundenen
* @param pusher Der Pusher-Thread des Clients, welcher aus dem Verzeichnis entfernt werden soll. * 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. * @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) { if (this.clients != null) {
int index = -1; int index = -1;
//Suche nach dem Element in dem Array
for (int i = 0; i < this.clients.length; i++) { 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; index = i;
break; break;
} }
} }
if (index != -1) { if (index != -1) {
Client[] temp = new Client[this.clients.length - 1]; Client[] temp = new Client[this.clients.length - 1];
for (int i = 0; i < index; i++) { //Teil des Arrays vor dem Index des zu entfernenden Elements kopieren.
temp[i] = this.clients[i]; System.arraycopy(this.clients, 0, temp, 0, index);
} //Teil des Arrays nach dem Index des zu entfernenden Elements 1 Index nach vorne kopieren.
for (int i = (index + 1); i < this.clients.length; i++) { System.arraycopy(this.clients, (index + 1), temp, index, (this.clients.length - (index + 1)));
temp[i - 1] = this.clients[i];
}
Client result = this.clients[index]; Client result = this.clients[index];
this.clients = temp; this.clients = temp;
Logger.getLogger(ClientStore.class.getName()).log(Level.INFO, "ClientStore: Client gelöscht"); 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 * @return Ein Array aus allen Streams
*/ */
public ObjectOutputStream[] getAllOutputStreams() { public ObjectOutputStream[] getAllOutputStreams() {
@ -98,15 +110,18 @@ public class ClientStore {
} }
/** /**
* Schließt den zu einem Thread gehörenden OutputStream * Funktion, die den zu einem Thread gehörenden OutputStream schließt.
* @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. * @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) { if (this.clients != null) {
int index = -1; int index = -1;
for (int i = 0; i < this.clients.length; i++) { for (int i = 0; i < this.clients.length; i++) {
if (clients[i].getPusher().equals(thread)) { if (this.clients[i].getSender().equals(sender)) {
index = i; index = i;
} }
} }

View file

@ -20,7 +20,8 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.PipedInputStream; import java.io.PipedInputStream;
import java.io.PipedOutputStream; import java.io.PipedOutputStream;
import java.net.*; import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import utils.Client; import utils.Client;
@ -28,13 +29,13 @@ import utils.Client;
/** /**
* Hauptklasse des Servers * Hauptklasse des Servers
* *
* @version 0.0.1 * @version 1.0.0
* @author eichehome * @author eichehome
*/ */
public class MainServer { 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 * @param args the command line arguments
*/ */
public static void main(String[] args) { public static void main(String[] args) {
@ -42,7 +43,7 @@ public class MainServer {
ClientStore clientStore = new ClientStore(); ClientStore clientStore = new ClientStore();
while (true) { while (true) {
Logger.getLogger(MainServer.class.getName()).log(Level.INFO, String.format("Main: Warte auf Clients")); 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")); Logger.getLogger(MainServer.class.getName()).log(Level.INFO, String.format("Main: Client verbunden"));
PipedOutputStream pipedOutputStream = new PipedOutputStream(); PipedOutputStream pipedOutputStream = new PipedOutputStream();
@ -57,16 +58,16 @@ public class MainServer {
Logger.getLogger(MainServer.class.getName()).log(Level.INFO, String.format("Main: Streams erstellt")); Logger.getLogger(MainServer.class.getName()).log(Level.INFO, String.format("Main: Streams erstellt"));
Thread threadRecive = new ClientReciveMessageThread(in, clientStore); 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")); Logger.getLogger(MainServer.class.getName()).log(Level.INFO, String.format("Main: Threads erstellt"));
threadPush.start(); threadSend.start();
threadRecive.start(); threadRecive.start();
Logger.getLogger(MainServer.class.getName()).log(Level.INFO, String.format("Main: Threads gestartet")); 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) { } catch (Exception ex) {

View file

@ -14,7 +14,6 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package test; package test;
import java.io.*; import java.io.*;
@ -22,26 +21,21 @@ import java.net.*;
import utils.Message; import utils.Message;
/** /**
* @author berdan * Dies ist eine Test-Klasse
*
* @author berdan, eichehome
*/ */
/*
Dies ist eine Test-Klasse
*/
public class MainClient { public class MainClient {
public MainClient() throws IOException, ClassNotFoundException { public MainClient() throws IOException, ClassNotFoundException {
System.out.println("[CLIENT] START"); System.out.println("[CLIENT] START");
Socket socket = new Socket( "localhost", 1236 ); Socket socket = new Socket("localhost", 1236);
System.out.println("[CLIENT] Debug1"); System.out.println("[CLIENT] Debug1");
ObjectOutputStream oboust = new ObjectOutputStream(socket.getOutputStream()); ObjectOutputStream oboust = new ObjectOutputStream(socket.getOutputStream());
System.out.println("[CLIENT] Debug2"); System.out.println("[CLIENT] Debug2");
ObjectInputStream obinstr = new ObjectInputStream(socket.getInputStream()); ObjectInputStream obinstr = new ObjectInputStream(socket.getInputStream());
System.out.println("[CLIENT] START1"); System.out.println("[CLIENT] START1");
Message senden = new Message( "berdan", "test" ); Message senden = new Message("berdan", "test");
System.out.println(senden); //nickname=berdan, message=test System.out.println(senden); //nickname=berdan, message=test
// Message senden // Message senden
@ -50,10 +44,9 @@ public class MainClient {
System.out.println("[CLIENT] NACHRICHT GESENDET"); System.out.println("[CLIENT] NACHRICHT GESENDET");
// Message erhalten // Message erhalten
Object erhalten = null; Object erhalten = null;
while(erhalten==null){ while (erhalten == null) {
erhalten = obinstr.readObject(); erhalten = obinstr.readObject();
System.out.println(erhalten); System.out.println(erhalten);
} }

View file

@ -16,57 +16,52 @@
*/ */
package test; package test;
import utils.FifoPipe;
import utils.Message;
/** /**
* Dies ist eine Test-Klasse
* *
* @author berdan * @author berdan, eichehome
*/ */
/*
Dies ist eine Test-Klasse
*/
public class PipeTest { public class PipeTest {
public static void main(String[] args) { public static void main(String[] args) {
/*FifoPipe pipe = new FifoPipe(); FifoPipe pipe = new FifoPipe();
System.out.println("Erstes Element: " + pipe.firstElement); // System.out.println("Erstes Element: " + pipe.firstElement);
System.out.println("Letztes Element: " + pipe.lastElement); // System.out.println("Letztes Element: " + pipe.lastElement);
Message el = new Message("Christian", "Test"); Message el = new Message("Christian", "Test");
pipe.setElement(el); pipe.setElement(el);
System.out.println("Angehängt"); System.out.println("Angehängt");
System.out.println("Erstes Element: " + pipe.firstElement); // System.out.println("Erstes Element: " + pipe.firstElement);
System.out.println("Letztes Element: " + pipe.lastElement); // System.out.println("Letztes Element: " + pipe.lastElement);
System.out.println("Erstes Element Inhalt: " + pipe.firstElement.getData().gebeData()); // System.out.println("Erstes Element Inhalt: " + pipe.firstElement.getData().getMessage());
System.out.println("Letztes Element Inhalt: " + pipe.lastElement.getData().gebeData()); // System.out.println("Letztes Element Inhalt: " + pipe.lastElement.getData().getMessage());
Message el2 = new Message("Christian", "Test"); Message el2 = new Message("Christian", "Test");
pipe.setElement(el2); pipe.setElement(el2);
System.out.println("Angehängt2"); System.out.println("Angehängt2");
System.out.println("Erstes Element: " + pipe.firstElement); // System.out.println("Erstes Element: " + pipe.firstElement);
System.out.println("Letztes Element: " + pipe.lastElement); // System.out.println("Letztes Element: " + pipe.lastElement);
System.out.println("Erstes Element Inhalt: " + pipe.firstElement.getData().gebeData()); // System.out.println("Erstes Element Inhalt: " + pipe.firstElement.getData().getMessage());
System.out.println("Letztes Element Inhalt: " + pipe.lastElement.getData().gebeData()); // System.out.println("Letztes Element Inhalt: " + pipe.lastElement.getData().getMessage());
Message pipeElement = pipe.getNextElement(); Message message = pipe.getNextElement();
System.out.println("Oben entnommen"); System.out.println("Oben entnommen");
System.out.println("Entnommen Inhalt: " + pipeElement.getData().gebeData()); System.out.println("Entnommen Inhalt: " + message.getMessage());
System.out.println("Erstes Element: " + pipe.firstElement); // System.out.println("Erstes Element: " + pipe.firstElement);
System.out.println("Letztes Element: " + pipe.lastElement); // System.out.println("Letztes Element: " + pipe.lastElement);
System.out.println("Erstes Element Inhalt: " + pipe.firstElement.getData().gebeData()); // System.out.println("Erstes Element Inhalt: " + pipe.firstElement.getData().getMessage());
System.out.println("Letztes Element Inhalt: " + pipe.lastElement.getData().gebeData()); // System.out.println("Letztes Element Inhalt: " + pipe.lastElement.getData().getMessage());
Message pipeElement2 = pipe.getNextElement(); Message message2 = pipe.getNextElement();
System.out.println("Oben entnommen2"); System.out.println("Oben entnommen2");
System.out.println("Entnommen Inhalt: " + pipeElement2.getData().gebeData()); System.out.println("Entnommen Inhalt: " + message2.getMessage());
System.out.println("Erstes Element: " + pipe.firstElement); // System.out.println("Erstes Element: " + pipe.firstElement);
System.out.println("Letztes Element: " + pipe.lastElement); // System.out.println("Letztes Element: " + pipe.lastElement);
//Wieso wills nicht funktionieren? //Wieso wills nicht funktionieren?
Message pipeElement3 = pipe.getNextElement(); Message message3 = pipe.getNextElement();
System.out.println("Oben entnommen3"); System.out.println("Oben entnommen3");
//System.out.println(pipeElement3.getData().gebeData()); System.out.println(message3.getMessage());
System.out.println("Erstes Element: " + pipe.firstElement); // System.out.println("Erstes Element: " + pipe.firstElement);
System.out.println("Letztes Element: " + pipe.lastElement); // System.out.println("Letztes Element: " + pipe.lastElement);
ArrayHelper test = new ArrayHelper();
*/
} }
} }

View file

@ -18,44 +18,64 @@ package utils;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.util.logging.Logger;
import java.util.logging.Level;
/** /**
* Dies Klasse stellt einen Client mit seinen Streams dar. * Dies Klasse stellt einen Client mit seinen Streams dar.
* *
* @version 1.0.0
* @author eichehome * @author eichehome
*/ */
public class Client { 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 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; private final Thread reciver;
/** /**
* Konstruktor * Konstruktor
*
* @param out Stream, um diesem Client Nachrichten schicken zu können. * @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 sender Zeiger auf den Thread, der die Nachrichten an den Client
* @param reciver Zeiger auf den Thread, der die Nachrichten eines Clients empfängt. * 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.out = out;
this.pusher = pusher; this.sender = sender;
this.reciver = reciver; this.reciver = reciver;
} }
/** /**
* Schreibe eine Nachricht in den OutputStream dieses Clients. * Schreibe eine Nachricht in den OutputStream dieses Clients.
*
* @param message Die zu verschickende Nachricht. * @param message Die zu verschickende Nachricht.
*/ */
public void writeMessage(Message message) { public void writeMessage(Message message) {
try { try {
this.out.writeObject(message); this.out.writeObject(message);
} catch (IOException ex) { } 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 * Getter für den OutputStream diese Clients
*
* @return Zeiger auf den Stream. * @return Zeiger auf den Stream.
*/ */
public ObjectOutputStream getOutputStream() { public ObjectOutputStream getOutputStream() {
@ -64,14 +84,16 @@ public class Client {
/** /**
* Getter für den Thread, der Nachrichten an diesen Client sendet. * Getter für den Thread, der Nachrichten an diesen Client sendet.
*
* @return Zeiger auf den Thread. * @return Zeiger auf den Thread.
*/ */
public Thread getPusher() { public Thread getSender() {
return this.pusher; return this.sender;
} }
/** /**
* Getter für den Thread, der Nchrichten an diesen Client sendet. * Getter für den Thread, der Nchrichten an diesen Client sendet.
*
* @return Zeiger auf den Thread. * @return Zeiger auf den Thread.
*/ */
public Thread getReciver() { public Thread getReciver() {