Letzte Kommentare hinzugefügt, Namen geupdatet und Dateien formatiert.
This commit is contained in:
parent
c1bb7a2070
commit
8ea1060c44
7 changed files with 703 additions and 530 deletions
|
@ -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,159 +14,299 @@ 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 {
|
||||||
|
|
||||||
private static JPanel contentPane;
|
/*
|
||||||
JTextField txtMessage;
|
Hier werden Objekte und Variablen deklariert, damit diese
|
||||||
private JTextField txtUsername;
|
in allen Methoden genutzt werden können.
|
||||||
public static String currentText = " ";
|
*/
|
||||||
public static int i = 0;
|
private static JPanel contentPane;
|
||||||
public static Object tosend = new Message("Leer", "Leer");
|
JTextField txtMessage;
|
||||||
public static Client t1;
|
private static JTextField txtUsername;
|
||||||
public static Socket socket;
|
public static String currentText = " ";
|
||||||
public static ObjectInputStream obinstr;
|
public static int i = 0;
|
||||||
public static ObjectOutputStream oboust;
|
public static Object tosend = new Message("Leer", "Leer");
|
||||||
|
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");
|
||||||
|
|
||||||
|
/*
|
||||||
|
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() {
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
Client1 frame = new Client1();
|
||||||
|
frame.setVisible(true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
start();
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
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();
|
||||||
|
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||||
|
setContentPane(contentPane);
|
||||||
|
contentPane.setLayout(null);
|
||||||
|
|
||||||
|
txtMessage = new JTextField();
|
||||||
|
txtMessage.setText("Message");
|
||||||
|
txtMessage.setBounds(20, 230, 218, 20);
|
||||||
|
contentPane.add(txtMessage);
|
||||||
|
txtMessage.setColumns(10);
|
||||||
|
|
||||||
|
txtUsername = new JTextField();
|
||||||
|
txtUsername.setText("Username");
|
||||||
|
txtUsername.setBounds(20, 11, 86, 20);
|
||||||
|
contentPane.add(txtUsername);
|
||||||
|
txtUsername.setColumns(10);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Beta Version des Clients
|
* Der Button "Send" nimmt die aktuelle Nachricht, welche im Textfeld
|
||||||
* @version 0.0.2
|
* "message" geschrieben wurde und schreibt diese als ein Message-Objekt
|
||||||
* @author berdan
|
* 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();
|
||||||
|
|
||||||
public static void main(String[] args) {
|
tosend = new Message(theusername, themessage);
|
||||||
t1 = new Client();
|
i = 1;
|
||||||
EventQueue.invokeLater(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
Client frame = new Client();
|
|
||||||
frame.setVisible(true);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
temp = new Message(theusername, themessage);
|
||||||
|
System.out.println("Button pressed");
|
||||||
|
|
||||||
try {
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
start();
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
oboust.writeObject(tosend);
|
||||||
|
oboust.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} catch (Exception k) {
|
||||||
|
print("KEINE VERBINDUNG");
|
||||||
|
}
|
||||||
|
|
||||||
public Client() {
|
if (temp.getMessage().equals("exit")) {
|
||||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
System.exit(0);
|
||||||
setBounds(100, 100, 450, 300);
|
}
|
||||||
contentPane = new JPanel();
|
|
||||||
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
|
|
||||||
setContentPane(contentPane);
|
|
||||||
contentPane.setLayout(null);
|
|
||||||
|
|
||||||
txtMessage = new JTextField();
|
txtMessage.setText("");
|
||||||
txtMessage.setText("Message");
|
|
||||||
txtMessage.setBounds(117, 29, 218, 20);
|
|
||||||
contentPane.add(txtMessage);
|
|
||||||
txtMessage.setColumns(10);
|
|
||||||
|
|
||||||
txtUsername = new JTextField();
|
}
|
||||||
txtUsername.setText("Username");
|
|
||||||
txtUsername.setBounds(21, 29, 86, 20);
|
|
||||||
contentPane.add(txtUsername);
|
|
||||||
txtUsername.setColumns(10);
|
|
||||||
|
|
||||||
JButton btnSend = new JButton("Send");
|
}
|
||||||
btnSend.addActionListener(new ActionListener() {
|
});
|
||||||
public void actionPerformed(ActionEvent arg0) {
|
|
||||||
|
|
||||||
String themessage = txtMessage.getText();
|
btnSend.setBounds(264, 229, 79, 23);
|
||||||
String theusername = txtUsername.getText();
|
contentPane.add(btnSend);
|
||||||
|
|
||||||
tosend = new Message(theusername, themessage);
|
/**
|
||||||
i = 1;
|
* Hier wird die textArea, auf welcher der Text ausgegeben wird
|
||||||
|
* initialisiert
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
textArea = new JTextArea(currentText);
|
||||||
|
textArea.setLineWrap(true);
|
||||||
|
textArea.setForeground(Color.BLACK);
|
||||||
|
textArea.setBackground(Color.LIGHT_GRAY);
|
||||||
|
textArea.setBounds(20, 42, 323, 176);
|
||||||
|
contentPane.add(textArea);
|
||||||
|
|
||||||
System.out.println("Button pressed");
|
/**
|
||||||
|
* 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) {
|
||||||
|
|
||||||
try {
|
txtUsername.setEditable(false);
|
||||||
oboust.writeObject(tosend);
|
txtUsername.setEnabled(false);
|
||||||
oboust.flush();
|
verbunden = true;
|
||||||
} catch (IOException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
btnStart.setBounds(116, 10, 89, 23);
|
||||||
|
contentPane.add(btnStart);
|
||||||
|
|
||||||
btnSend.setBounds(345, 28, 79, 23);
|
}
|
||||||
contentPane.add(btnSend);
|
|
||||||
|
|
||||||
JTextArea textArea = new JTextArea(currentText);
|
/**
|
||||||
textArea.setLineWrap(true);
|
* In der Print-Methode wird der neue Text (also eine neue Nachricht) auf
|
||||||
textArea.setForeground(Color.WHITE);
|
* die textArea abgebildet.
|
||||||
textArea.setBackground(Color.LIGHT_GRAY);
|
*/
|
||||||
textArea.setBounds(20, 60, 323, 176);
|
public static void print(String neuerText) {
|
||||||
contentPane.add(textArea);
|
currentText = neuerText + "\n" + currentText;
|
||||||
}
|
|
||||||
|
|
||||||
public static void print(JTextArea textArea, String asd){
|
textArea.setText(currentText);
|
||||||
currentText = asd + "\n" + currentText;
|
}
|
||||||
textArea.setText(currentText);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void start() throws IOException, ClassNotFoundException{
|
/**
|
||||||
Scanner scan = new Scanner(System.in);
|
* 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 {
|
||||||
|
|
||||||
JTextArea textArea = new JTextArea(currentText);
|
while (!verbunden) {
|
||||||
textArea.setLineWrap(true);
|
Thread.sleep(100);
|
||||||
textArea.setForeground(Color.WHITE);
|
}
|
||||||
textArea.setBackground(Color.BLACK);
|
|
||||||
textArea.setBounds(20, 60, 323, 176);
|
|
||||||
contentPane.add(textArea);
|
|
||||||
|
|
||||||
socket = new Socket( "localhost", 1236 );
|
txtUsername.setEnabled(false);
|
||||||
oboust = new ObjectOutputStream(socket.getOutputStream());
|
Scanner scan = new Scanner(System.in);
|
||||||
obinstr = new ObjectInputStream(socket.getInputStream());
|
|
||||||
|
|
||||||
Object erhalten = null;
|
try {
|
||||||
Message message = new Message("leer", "leer");
|
socket = new Socket("localhost", 1236);
|
||||||
|
oboust = new ObjectOutputStream(socket.getOutputStream());
|
||||||
|
obinstr = new ObjectInputStream(socket.getInputStream());
|
||||||
|
print("VERBINDUNG HERGESTELLT");
|
||||||
|
} catch (Exception KeineSocket) {
|
||||||
|
print("SERVER ANTWORTET NICHT");
|
||||||
|
try {
|
||||||
|
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);
|
||||||
|
|
||||||
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 {
|
|
||||||
Thread.sleep(1000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
Object erhalten = null;
|
||||||
oboust.close();
|
Message message = new Message("leer", "leer");
|
||||||
obinstr.close();
|
|
||||||
socket.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,324 +20,293 @@ import java.awt.event.ActionEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hauptklasse des Clients
|
* Hauptklasse des Clients
|
||||||
|
*
|
||||||
* @version 0.1.3
|
* @version 0.1.3
|
||||||
* @author berdan
|
* @author berdan
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
public class Client1 extends JFrame {
|
public class Client1 extends JFrame {
|
||||||
|
|
||||||
|
/*
|
||||||
/*
|
|
||||||
Hier werden Objekte und Variablen deklariert, damit diese
|
Hier werden Objekte und Variablen deklariert, damit diese
|
||||||
in allen Methoden genutzt werden können.
|
in allen Methoden genutzt werden können.
|
||||||
*/
|
*/
|
||||||
private static JPanel contentPane;
|
private static JPanel contentPane;
|
||||||
JTextField txtMessage;
|
JTextField txtMessage;
|
||||||
private static 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 Client1 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 boolean verbunden = false;
|
||||||
public static JTextArea textArea = new JTextArea();
|
public static JTextArea textArea = new JTextArea();
|
||||||
public static int anzahlVersuche = 0; //Ist gleich die AN
|
public static int anzahlVersuche = 0; //Ist gleich die AN
|
||||||
public static int anzahlRekursionen = 0;
|
public static int anzahlRekursionen = 0;
|
||||||
public static Message temp = new Message("leer", "leer");
|
public static Message temp = new Message("leer", "leer");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In der main Methode wird das GUI erstellt und die
|
In der main Methode wird das GUI erstellt und die
|
||||||
start() Methode aufgerufen.
|
start() Methode aufgerufen.
|
||||||
*/
|
*/
|
||||||
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
t1 = new Client1();
|
||||||
|
EventQueue.invokeLater(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
Client1 frame = new Client1();
|
||||||
|
frame.setVisible(true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
public static void main(String[] args) throws InterruptedException {
|
try {
|
||||||
t1 = new Client1();
|
start();
|
||||||
EventQueue.invokeLater(new Runnable() {
|
} catch (ClassNotFoundException e) {
|
||||||
public void run() {
|
// TODO Auto-generated catch block
|
||||||
try {
|
e.printStackTrace();
|
||||||
Client1 frame = new Client1();
|
} catch (IOException e) {
|
||||||
frame.setVisible(true);
|
// TODO Auto-generated catch block
|
||||||
} catch (Exception e) {
|
e.printStackTrace();
|
||||||
e.printStackTrace();
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
/*
|
||||||
try {
|
|
||||||
start();
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
In der Methode Client1() wird das GUI
|
In der Methode Client1() wird das GUI
|
||||||
und die Befehle die durch einen Click des
|
und die Befehle die durch einen Click des
|
||||||
Button's ausgelöst werden festgelegt
|
Button's ausgelöst werden festgelegt
|
||||||
*/
|
*/
|
||||||
|
public Client1() {
|
||||||
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
setBounds(100, 100, 450, 300);
|
||||||
|
contentPane = new JPanel();
|
||||||
|
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||||
|
setContentPane(contentPane);
|
||||||
|
contentPane.setLayout(null);
|
||||||
|
|
||||||
public Client1() {
|
txtMessage = new JTextField();
|
||||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
txtMessage.setText("Message");
|
||||||
setBounds(100, 100, 450, 300);
|
txtMessage.setBounds(20, 230, 218, 20);
|
||||||
contentPane = new JPanel();
|
contentPane.add(txtMessage);
|
||||||
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
|
txtMessage.setColumns(10);
|
||||||
setContentPane(contentPane);
|
|
||||||
contentPane.setLayout(null);
|
|
||||||
|
|
||||||
txtMessage = new JTextField();
|
txtUsername = new JTextField();
|
||||||
txtMessage.setText("Message");
|
txtUsername.setText("Username");
|
||||||
txtMessage.setBounds(20, 230, 218, 20);
|
txtUsername.setBounds(20, 11, 86, 20);
|
||||||
contentPane.add(txtMessage);
|
contentPane.add(txtUsername);
|
||||||
txtMessage.setColumns(10);
|
txtUsername.setColumns(10);
|
||||||
|
|
||||||
txtUsername = new JTextField();
|
/**
|
||||||
txtUsername.setText("Username");
|
* Der Button "Send" nimmt die aktuelle Nachricht, welche im Textfeld
|
||||||
txtUsername.setBounds(20, 11, 86, 20);
|
* "message" geschrieben wurde und schreibt diese als ein Message-Objekt
|
||||||
contentPane.add(txtUsername);
|
* in den Output-Stream an den Server, falls die Socket bereits
|
||||||
txtUsername.setColumns(10);
|
* 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();
|
||||||
Der Button "Send" nimmt die aktuelle Nachricht,
|
String theusername = txtUsername.getText();
|
||||||
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
|
tosend = new Message(theusername, themessage);
|
||||||
die GUI beendet.
|
i = 1;
|
||||||
*/
|
|
||||||
|
|
||||||
JButton btnSend = new JButton("Send");
|
temp = new Message(theusername, themessage);
|
||||||
btnSend.addActionListener(new ActionListener() {
|
System.out.println("Button pressed");
|
||||||
public void actionPerformed(ActionEvent arg0) {
|
|
||||||
|
|
||||||
if(verbunden){
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
|
||||||
String themessage = txtMessage.getText();
|
try {
|
||||||
String theusername = txtUsername.getText();
|
try {
|
||||||
|
oboust.writeObject(tosend);
|
||||||
tosend = new Message(theusername, themessage);
|
oboust.flush();
|
||||||
i = 1;
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
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) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
} catch( Exception k){
|
|
||||||
print("KEINE VERBINDUNG");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(temp.getMessage().equals("exit")){
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
txtMessage.setText("");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
btnSend.setBounds(264, 229, 79, 23);
|
|
||||||
contentPane.add(btnSend);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Hier wird die textArea, auf welcher der Text ausgegeben wird
|
|
||||||
initialisiert
|
|
||||||
|
|
||||||
*/
|
|
||||||
textArea = new JTextArea(currentText);
|
|
||||||
textArea.setLineWrap(true);
|
|
||||||
textArea.setForeground(Color.BLACK);
|
|
||||||
textArea.setBackground(Color.LIGHT_GRAY);
|
|
||||||
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);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
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.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
public static void start() throws IOException, ClassNotFoundException, InterruptedException{
|
|
||||||
|
|
||||||
while(!verbunden){
|
|
||||||
Thread.sleep(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
txtUsername.setEnabled(false);
|
|
||||||
Scanner scan = new Scanner(System.in);
|
|
||||||
|
|
||||||
try{
|
|
||||||
socket = new Socket( "localhost", 1236 );
|
|
||||||
oboust = new ObjectOutputStream(socket.getOutputStream());
|
|
||||||
obinstr = new ObjectInputStream(socket.getInputStream());
|
|
||||||
print("VERBINDUNG HERGESTELLT");
|
|
||||||
}catch(Exception KeineSocket){
|
|
||||||
print("SERVER ANTWORTET NICHT");
|
|
||||||
try {
|
|
||||||
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();
|
} catch (Exception k) {
|
||||||
System.exit(0);
|
print("KEINE VERBINDUNG");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
if (temp.getMessage().equals("exit")) {
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
txtMessage.setText("");
|
||||||
|
|
||||||
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
|
btnSend.setBounds(264, 229, 79, 23);
|
||||||
es 5 mal im Abstand von 2 Sekunden nochmal eine Nachricht
|
contentPane.add(btnSend);
|
||||||
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.
|
* Hier wird die textArea, auf welcher der Text ausgegeben wird
|
||||||
|
* initialisiert
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
textArea = new JTextArea(currentText);
|
||||||
|
textArea.setLineWrap(true);
|
||||||
|
textArea.setForeground(Color.BLACK);
|
||||||
|
textArea.setBackground(Color.LIGHT_GRAY);
|
||||||
|
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);
|
||||||
|
|
||||||
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());
|
* In der Print-Methode wird der neue Text (also eine neue Nachricht) auf
|
||||||
String Ausgeben = message.getTime() + " [" + message.getUsername() + "] " + message.getMessage();
|
* die textArea abgebildet.
|
||||||
print(Ausgeben);
|
*/
|
||||||
//System.out.println("[CLIENT] NACHRICHT ERHALTEN");
|
public static void print(String neuerText) {
|
||||||
|
currentText = neuerText + "\n" + currentText;
|
||||||
|
|
||||||
oboust.flush();
|
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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static void start() throws IOException, ClassNotFoundException, InterruptedException {
|
||||||
|
|
||||||
catch(SocketException h){
|
while (!verbunden) {
|
||||||
System.out.println(h);
|
Thread.sleep(100);
|
||||||
print("VERBINDUNGSABBRUCH");
|
}
|
||||||
anzahlVersuche++;
|
|
||||||
|
|
||||||
Thread.sleep(2000);
|
txtUsername.setEnabled(false);
|
||||||
|
Scanner scan = new Scanner(System.in);
|
||||||
|
|
||||||
|
try {
|
||||||
|
socket = new Socket("localhost", 1236);
|
||||||
|
oboust = new ObjectOutputStream(socket.getOutputStream());
|
||||||
|
obinstr = new ObjectInputStream(socket.getInputStream());
|
||||||
|
print("VERBINDUNG HERGESTELLT");
|
||||||
|
} catch (Exception KeineSocket) {
|
||||||
|
print("SERVER ANTWORTET NICHT");
|
||||||
|
try {
|
||||||
|
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);
|
||||||
|
|
||||||
if(anzahlVersuche==5){
|
}
|
||||||
anzahlVersuche = 0;
|
|
||||||
anzahlRekursionen++;
|
|
||||||
|
|
||||||
if(anzahlRekursionen == 10){
|
Object erhalten = null;
|
||||||
print("KEINE ANTWORT, CLIENT WIRD BEENDET");
|
Message message = new Message("leer", "leer");
|
||||||
Thread.sleep(10000);
|
|
||||||
System.exit(0);
|
|
||||||
|
|
||||||
}
|
/**
|
||||||
|
* 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");
|
||||||
|
|
||||||
start();
|
oboust.flush();
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
} catch (SocketException h) {
|
||||||
catch(Exception f){
|
System.out.println(h);
|
||||||
Thread.sleep(1000);
|
print("VERBINDUNGSABBRUCH");
|
||||||
}
|
anzahlVersuche++;
|
||||||
|
|
||||||
}
|
Thread.sleep(2000);
|
||||||
|
|
||||||
/*
|
if (anzahlVersuche == 5) {
|
||||||
Nach dem Abbruch der While Schleife, was nur bei der
|
anzahlVersuche = 0;
|
||||||
Nachricht exit passiert, schließt der Client
|
anzahlRekursionen++;
|
||||||
den ObjectOutputstream, Objectinputstream und den Socket
|
|
||||||
und beendet dann das Programm
|
|
||||||
*/
|
|
||||||
|
|
||||||
oboust.close();
|
if (anzahlRekursionen == 10) {
|
||||||
obinstr.close();
|
print("KEINE ANTWORT, CLIENT WIRD BEENDET");
|
||||||
socket.close();
|
Thread.sleep(10000);
|
||||||
|
System.exit(0);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
@ -42,18 +63,18 @@ public class ClientReciveMessageThread extends Thread {
|
||||||
boolean continueLoop = true;
|
boolean continueLoop = true;
|
||||||
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);
|
||||||
stream.flush();
|
stream.flush();
|
||||||
Logger.getLogger(ClientReciveMessageThread.class.getName()).log(Level.INFO, String.format("Reciveing Thread %d: Weitergeleitet", this.getId()));
|
Logger.getLogger(ClientReciveMessageThread.class.getName()).log(Level.INFO, String.format("Reciveing Thread %d: Weitergeleitet", this.getId()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
Loading…
Reference in a new issue