Mein eigener Messenger und dessen Probleme

Jatoll

Bekanntes Mitglied
Hallo,
da ich noch öfter Frage zu meinem selbst gebauten Messenger haben werde dachte ich mir ist ein eigenes Thema am besten dazu geeignet Hilfe zu suchen :)
Erstmal, die Grundlage ist "O'Reilly - Java von Kopf bis Fuß"... dort stand ein ganz einfacher chatserver und client beschrieben und das habe ich alles abgetippt und erweitere es nun und passe es meinen Vorstellungen an.
gerade habe ich folgendes Problem:

Client:
Java:
private void netzwerkEinrichten() {
		try {
			sock = new Socket("127.0.0.1", 63551);
			InputStreamReader streamReader = new InputStreamReader(sock
					.getInputStream());
			reader = new BufferedReader(streamReader);
			writer = new PrintWriter(sock.getOutputStream());
			writer.println("**** "+meinName +" joined the conversation - ("+ this.getDateAndTime()+") ****");
			writer.flush();
			System.out.println("Netzwerkverbindung steht");

		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

Die Zeit wird hier mit der Methode this.getDateAndTime abgefragt und an den String im writer geklatscht... das passiert allerdings im Client... bei Nachrichten hab ich das selbe gemacht. genau so wird auch der Name (Name des Rechners) über den writer mit übergeben... das würde ich aber alles gerne in der Server Datei tun... ich weiß nur nicht wie...
also ich muss die möglichkeit finden den Namen irgendwie mit zu übergeben aber halt nicht im Text selber, denn die Ausgabe soll Später so aussehen:

ABC - (09.02.2011 10:45:13):
Hallo Leute

Die Zeit soll vom Server gesetzt werden weil es schon zu unterschieden kommt wenn die rechner nicht synchonisiert sind und das is ja doof wenn die nachrichten so rüber kommen:

ABC - (09.02.2011 10:45:13):
Hallo Leute
XYZ - (09.02.2011 10:39:08):
Ja dir auch hallo
 

Blakh

Bekanntes Mitglied
Verstehe das Problem nicht ganz. Die Zeit, wann welche Nachricht gesendet/empfangen wird, wird normalerweise doch auch vom Client festgelegt. Da muss nix synchronisiert werden. Die Zeit sollte ja auch nicht mitgeschickt werden, sondern der Client fügt selbständig immer diese hinzu.

Und wo genau liegt jetzt das Problem?
 

Jatoll

Bekanntes Mitglied
die zeit is eher weniger das problem... ich will halt den namen des Rechners mit übergeben, nur halt nicht im text selber... das mit der zeit krieg ich schon irgendwie hin...
 

Jatoll

Bekanntes Mitglied
XML sagt mir leider gar nix ... also gehört hab ichs schon öfter aber was genau das ist und wofür weiß ich ehrlich gesagt nich
 

HoaX

Top Contributor
Dann tipps doch mal bei Google ein. Und dann kannst du dir auch gleich mal XMPP anschauen. Das ist ein fertiges Protokoll fürs Chatten.
 

Jatoll

Bekanntes Mitglied
Neue Frage:

ich will die verbindung zum server trennen wenn das programm geschlossen wird oder abschmiert (am besten noch mit ner meldung)... wie mach ich sowas?
 

DerEisteeTrinker

Bekanntes Mitglied
Dafür erschuf der Programmierer das finally, hilft aber nicht unbedingt, wenn das Programm abschmiert. Wenn eine Anwendung "abschmiert" ist das ein Zeichen für schlechte Programmierung, denn man sollte als Programmierer immer mit dem daU (dümmster anzunehmender User) rechnen. Ich habe gelernt, dass man nicht dumm genug denken kann, Stichwort: Chaos-Theorie.
 

Jatoll

Bekanntes Mitglied
ok, das weiß ich ja... nur wie siehts aus mit taskmanager und Prozess beenden? ... das hat ja nicht viel mit ne dummen user zu tun...
aber wie genau funktioniert dieses finally?
is das eine extra methode?
 

Jatoll

Bekanntes Mitglied
ich versteh nicht ganz wie und wo ich diesen finally bock einsetzen muss... er wird ja IMMER ausgeführt, ob etwas klappt oder nicht und irgendwie macht ers nicht wenn das programm geschlossen wird sondern direkt nach dem Try - Catch ... hab ich das soweit schonmal richtig verstanden?
 

Jatoll

Bekanntes Mitglied
wie kann ich eine "online-users" liste erstellen?
also ich will zumindest die IPs abgreifen können die gerade auf den Server zugreifen... aber ich weiß nicht wie das geht und finde da auch nicht wirklich was zu.
 

DerEisteeTrinker

Bekanntes Mitglied
Dazu wirst du wohl auf dem Server speichern müssen, wer sich angemeldet hat und noch nicht abgemeldet hat. Das Problem ist nur, dass du eventuell nicht mitbekommst, wenn ein Client außerplanmäßig geschlossen wurde
 
G

Gonzo17

Gast
Dazu wirst du wohl auf dem Server speichern müssen, wer sich angemeldet hat und noch nicht abgemeldet hat. Das Problem ist nur, dass du eventuell nicht mitbekommst, wenn ein Client außerplanmäßig geschlossen wurde

Man kann doch von Zeit zu Zeit mal nen Ping zum Client schicken, wenn keine Antwort kommt, ist er eben nicht mehr da.
 

DerEisteeTrinker

Bekanntes Mitglied
Man kann doch von Zeit zu Zeit mal nen Ping zum Client schicken, wenn keine Antwort kommt, ist er eben nicht mehr da.

Kann man, aber da würde ich mich nicht drauß verlassen. Denn was ist, wenn du sagst, dass die Firewall einen Ping ins Nirvana verschwinden lassen soll. Dann hast das Problem, dass der Server den Client als Offline registriert, der Client aber immernoch da ist, dann musst du dich laufend neu Anmelden und da sind die Schreie der Benutzer schon vorprogrammiert.
 

Jatoll

Bekanntes Mitglied
also der server merkt wenn jemand nicht mehr verbunden ist ... dann kommt ne exception und in diese hab ich schon eingebaut, dass ne nachricht kommt "Jemand hat den Chat verlassen!" ... nur will ich unter anderem halt hinkriegen, dass da dann der name kommt.
 
G

Gonzo17

Gast
also der server merkt wenn jemand nicht mehr verbunden ist ... dann kommt ne exception und in diese hab ich schon eingebaut, dass ne nachricht kommt "Jemand hat den Chat verlassen!" ... nur will ich unter anderem halt hinkriegen, dass da dann der name kommt.

Weiß jetzt nicht wie das konkret aussieht, aber ist die Information nicht irgendwie in der Exception enthalten? Da müsste doch irgendwie stehen, bei welcher Verbindung es zu Problemen kam, oder?
 

xehpuk

Top Contributor
Also der Socket müsste in dem Kontext direkt ansprechbar sein, da die Exception ja wegen des Zugriffs auf den Socket ausgelöst wird.
 

xehpuk

Top Contributor
nee da steht überall was mit Unknown Source...
Das sagt dir ja nur, dass nicht auf den Quelltext zugegriffen werden konnte.
Ich weiß jetzt auch nicht, wie du das überhaupt machst, könntest ja deinen Code zeigen.

Hier mal ein abgespecktes Beispiel:
Java:
public class ChatServer extends Thread {
	private final ServerSocket serverSocket;
	
	public ChatServer(final ServerSocket serverSocket) {
		this.serverSocket = serverSocket;
	}
	
	@Override
	public void run() {
		while (!isInterrupted()) {
			final Socket socket;
			try {
				socket = serverSocket.accept();
				System.out.println("In: " + socket);
				new Thread() {
					@Override
					public void run() {
						try {
							final BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
							String input;
							while ((input = reader.readLine()) != null)
								System.out.println(socket + ": " + input);
						} catch (IOException e) {
							System.out.println("Out: " + socket);
						}
					}
				}.start();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) throws IOException {
		new ChatServer(new ServerSocket(1337)).start();
	}
}
 

Jatoll

Bekanntes Mitglied
@xehpuk:
die ip fragste jetzt aber auch nicht ab oder?

EDIT:
ich will ja nur wissen wie ich in der Serverdatei die IPs der angemeldeten Clients einlesen kann...
 
Zuletzt bearbeitet:

xehpuk

Top Contributor
wofür ist eigentlich dieses @Override?
Das ist eine Annotation.
@Override—the @Override annotation informs the compiler that the element is meant to override an element declared in a superclass (overriding methods will be discussed in the the lesson titled "Interfaces and Inheritance").
Java:
   // mark method as a superclass method
   // that has been overridden
   @Override 
   int overriddenMethod() { }
While it's not required to use this annotation when overriding a method, it helps to prevent errors. If a method marked with @Override fails to correctly override a method in one of its superclasses, the compiler generates an error.
Annotations (The Java™ Tutorials > Learning the Java Language > Classes and Objects)
Kurz gesagt: Sie sagt dem Compiler, dass diese Methode eine andere überschreibt. Stellt der Compiler fest, dass dies nicht stimmt, gibt er einen Fehler aus. Der Zweck dahinter ist, dass man so Tippfehler sofort entdeckt und wenn man die Signatur der Operation in der Superklasse/dem Interface ändert oder sie gar löscht, meckert der Compiler dann auch, sodass man darauf aufmerksam gemacht wird, dass dies weitere Auswirkungen hat.

@xehpuk:
die ip fragste jetzt aber auch nicht ab oder?
Indirekt schon, denn ich gebe sie auf der Konsole aus. Probiers mal mit den Gettern, die "Address" beinhalten. Davon wirds wohl eine sein. :p
 

Java-Freak

Bekanntes Mitglied
Also man sollte noch dazu sagen, dass @Override für das Programm völlig unwichtig ist und nur zum besseren Verständnis des Codes da ist.
 

Jatoll

Bekanntes Mitglied
Das sagt dir ja nur, dass nicht auf den Quelltext zugegriffen werden konnte.
Ich weiß jetzt auch nicht, wie du das überhaupt machst, könntest ja deinen Code zeigen.

Hier mal ein abgespecktes Beispiel:
Java:
public class ChatServer extends Thread {
	private final ServerSocket serverSocket;
	
	public ChatServer(final ServerSocket serverSocket) {
		this.serverSocket = serverSocket;
	}
	
	@Override
	public void run() {
		while (!isInterrupted()) {
			final Socket socket;
			try {
				socket = serverSocket.accept();
				System.out.println("In: " + socket);
				new Thread() {
					@Override
					public void run() {
						try {
							final BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
							String input;
							while ((input = reader.readLine()) != null)
								System.out.println(socket + ": " + input);
						} catch (IOException e) {
							System.out.println("Out: " + socket);
						}
					}
				}.start();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) throws IOException {
		new ChatServer(new ServerSocket(1337)).start();
	}
}

Also ich hab das mal in Eclipse rüber kopiert und gestartet... da wird nix ausgegeben... ich kann nur schreiben und dann stehts da... versteh ich jetzt nicht so wirklich, wie ich da die ip erfahren kann ???:L
 

Jatoll

Bekanntes Mitglied
Ok, in der Zwischenzeit mal was anderes:

Java:
frame.setDefaultCloseOperation(this.closingOnX());
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	}
private int closingOnX(){
	writer.println("**** " + meinName + " left the conversation - ("
	+ this.getDateAndTime() + ") ****");
writer.flush();
return 0;
}

ich will nun das hier ausgeben wenn jemand den Chat verlässt... Problem ist aber, dass es direkt zu beginn ausgeführt wird... also die Methode closingOnX().
sie soll aber nur ausgeführt werden wenn jemand das Fenster schließt... kann mir da jemand helfen?
 

HoaX

Top Contributor
Dein Client sollte nicht dafür zuständig sein diese Meldung zu bringen. Und ein richtiges Protokoll wäre auch nicht schlecht, z.B. IRC oder XMPP.

Dein Server sollte User-Objekte halten, in denen Name, Socket, usw gespeichert ist. Der Client braucht immer nur normal die Verbindung trennen und der Server kann kann anhand des User-Objektes herausfinden welcher Benutzer nun gegangen ist und eine entsprechende Nachricht verteilen.
 

Jatoll

Bekanntes Mitglied
ja ich höre hier ja schon viel davon was der server alles tun sollte nur sagt mir keiner wie es gemacht wird ... bis jetzt hab ich nur, dass der Server ne exception schmeißt wenn jemand geht (die allerdings gefangen wird) und dann ne meldung kommt "jemand hat den chat verlassen" ... und deshalb hab ich ja schon ein paar mal gefragt wie man dann überhaupt die ip oder sonst was zur zuordnung der clients abrufen kann (vom server aus)
 
G

Gonzo17

Gast
und deshalb hab ich ja schon ein paar mal gefragt wie man dann überhaupt die ip oder sonst was zur zuordnung der clients abrufen kann (vom server aus)

Dein Server sollte User-Objekte halten, in denen Name, Socket, usw gespeichert ist.

Beantwortet das nicht die Frage? In einem User-Objekt stehen die Informationen und bei einer SocketException müsstest du doch auch wissen vol welchem Socket das kommt. Darüber kannst du es dann zuordnen. Das Code-Beispiel von xehpuk zeigt dir ja auch, wie du es machen kannst.
 

Jatoll

Bekanntes Mitglied
ich hab jetzt endlich mal herausgefunden, dass man mit .getInetAddress() vom server aus die IP der clients abrufen kann (mehr wollte ich doch auch gar nicht wissen) ... jetzt werde ich damit eine Hashmap oder Arraylist erstellen, in denen IP und Name sind und dann einfach beim ein und ausloggen aktualisieren und neu ausgeben in dem "Online-Users" fenster...
ich denke Hashmap eignet sich da besser oder?
 
G

Gonzo17

Gast
Wie gesagt, mach lieber eine Liste mit User-Objekten. Denn wenn du eine HashMap hast und da zB die IP-Adresse der Key ist, dann wirst du umgekehrt nicht an die IP-Adresse kommen, wenn du nur den Namen (oder andere Infos des Benutzers) hast. Bei einer Liste von Usern kannst du dann über die Liste iterieren, jedes User-Objekt nach einer bestimmten Information abfragen und hast dann hinterher wirklich den "ganzen User in der Hand".
 

Jatoll

Bekanntes Mitglied
ja ok, klingt ganz logisch, aber ich weiß gerade nicht ob ich das auch so umsetzen kann wie du sagst... ich hab sowas wie "user anlegen" noch nie gemacht... Hashmap würd ich noch hinkriegen.
 

HoaX

Top Contributor
Bei der HashMap mit IP wirst du Probleme bekommen, wenn zwei Benutzer hinter dem selben NAT-Gateway deinen Chat betreten, da dann beide die selbe IP haben.
 
G

Gonzo17

Gast
Wie man das konkret am besten umsetzt, weiß ich selbst auch nicht, aber ich stells mir recht einfach vor. Einfach mal eine Klasse "User" anlegen, die bestimmte Attribute hat, die du eben brauchst: Name, IP-Adresse/Socket, usw. Dann machst du einen oder mehrere Konstruktoren und für die Attribute jeweils Getter und Setter (falls notwendig, Name wird wahrscheinlich zB eher nicht verändert, falls du das in deinem Chat fest pro registrietem Benutzer hast).
 

Jatoll

Bekanntes Mitglied
dann brauch ich ja aber trotzdem noch sowas wie eine hashmap, in die die ganzen objekte dann einen eintrag schreiben und aus der sie beim logout wieder gelöscht werden oder?
 
Zuletzt bearbeitet:
G

Gonzo17

Gast
Ja, aber keine HashMap, sondern eine normale Liste. Du brauchst ja keinen Key, um an das User-Objekt zu kommen.
 
G

Gonzo17

Gast
In dem Moment, in dem du "merkst", dass der User offline ist, gibst du eine Nacht im Chat aus ("Karlchen hat den Chat verlassen.") und löschst den User "Karlchen" aus der Liste. Falls deine Namen eindeutig und nicht veränderbar sind, kannst du nach einem User mit dem Namen "Karlchen" suchen. Ansonsten musst du dir etwas ausdenken.
 

Jatoll

Bekanntes Mitglied
gut aber ich kann beim login bzw. anlegen eines neuen users prüfen ob die IP schon vergeben ist und dann sagen "Sorry aber IP is schon weg!" oder? und was is überhaupt ein NAT-Gateway? ich dachte immer jedes gerät im netz hat eine eindeutige IP?
 
G

Gonzo17

Gast
ich dachte immer jedes gerät im netz hat eine eindeutige IP?

Nein, davon sollte man nicht ausgehen. Schau dir zum Beispiel mal das an: Proxy
Kurz beschrieben heißt das, dass man über einen Proxy (quasi ein "Vermittler") ins Internet gehen kann, dh alle Anfragen (zB im Browser) werden nicht direkt ins Internet geleitet, sondern gehen über den Proxy, somit "sieht" man dich nicht im Internet. Gehen mehrere Leute über einen Proxy ins Internet, haben sie auch alle die gleiche IP-Adresse.
 

Java-Freak

Bekanntes Mitglied
Definiere lieber ein Klasse "User", die eine IP hat und einen Anzeigenamen und nehm dann eine LinkedList<User> (wahlweise auch ArrayList). Du kannst ja dann Getter/Setter schreiben, z.b. userxy.getIP() und userxy.getName()
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Queenman Interface Mein Microsoft Visual Studio Code zeigt komische Dinge & Menüs an Allgemeine Java-Themen 9
B Wie kann ich mein 8 Klassen Gebilde objektorientierter schreiben? Allgemeine Java-Themen 114
Tiago1234 Warum hängt sich mein Programm auf? Allgemeine Java-Themen 22
J Mein Frame friert ein beim Uploaden Allgemeine Java-Themen 4
Drachenbauer Wie sorge ich dafür, dass mein Spiel die ini-Datei in der Resourcen-ordner des Projektes schreibt? Allgemeine Java-Themen 5
I File ausführen und mein Programm bearbeiten lassen Allgemeine Java-Themen 11
M Brainstorming für mein Projekt Allgemeine Java-Themen 30
R Wo ist mein Fehler in der Methode DRINGEND Allgemeine Java-Themen 9
R Wo ist mein Fehler in diesem Code Allgemeine Java-Themen 7
M Suche aktuelle Apache Poi Bibliothek zum Einbinden in mein Programm Allgemeine Java-Themen 2
T log4j2 Wo liegt mein Logfile? Allgemeine Java-Themen 3
Thallius Warum läst mein replace die Klammern drin? Allgemeine Java-Themen 10
O Mein JButton Array funktioniert nicht Allgemeine Java-Themen 3
C Durch klicken von Button in GUI wird leeres Fenster geöffnet und nicht mein Spiel "Memory" Allgemeine Java-Themen 13
G Mein PDF Projekt mit iText Allgemeine Java-Themen 2
K Was ist mein Fehler? Allgemeine Java-Themen 2
itwestnet Mein Java-Programm läuft nicht in China Allgemeine Java-Themen 4
Thallius App-Sprache in der App ändern. Wo ist mein Denkfehler? Allgemeine Java-Themen 6
M Mein erstes TicTacToe :-) Allgemeine Java-Themen 3
A Applet Mein Applet verursacht Browserabsturz Allgemeine Java-Themen 8
Ollek MVC - Anwendung auf mein Projekt Allgemeine Java-Themen 18
K Wo ist mein Fehler? Allgemeine Java-Themen 21
C Hilfe! Mein Java mag nich mehr ganz... Allgemeine Java-Themen 11
F VideoIntro für mein Programm Allgemeine Java-Themen 2
A Wie lasse ich mein Programm als Daemon laufen? Allgemeine Java-Themen 4
A Wie liefere ich mein Java-Programm richtig aus? Allgemeine Java-Themen 10
G Entscheidungsproblem für mein Vorhaben, zwischen Java und C# Allgemeine Java-Themen 35
G Wie kann ich in mein Programm eine Updatefunktion einbauen Allgemeine Java-Themen 3
E Wie bekomme ich mein Image in das Fenster Allgemeine Java-Themen 2
V Beratung zum Bestimmen der "Mittel"(Java,Sql) mein Allgemeine Java-Themen 3
S mit welchem befehl kann ich mein programm autom. schließen Allgemeine Java-Themen 3
R Mein Applet läuft in der IDE aber nicht. Allgemeine Java-Themen 2
M Bitte Testen: Mein Multi-File Editor Allgemeine Java-Themen 30
B Fehler:Mein Applet kann nicht auf zwei txt-Dateien zugreifen Allgemeine Java-Themen 2
C Warum wartet mein thread nicht? Allgemeine Java-Themen 2
F Datei auslesen - wo ist mein Fehler? Allgemeine Java-Themen 9
T läuft mein Programm schon? - wie feststellen Allgemeine Java-Themen 6
T Warum mein such-tool schneller als Windows such-tool? Allgemeine Java-Themen 5
A Wie mach ich, das mein Button schneller reagiert. Allgemeine Java-Themen 13
A mein Frame wird nicht schnell genung aktualisiert Allgemeine Java-Themen 7
G JFrame nimmt mein Image nicht Allgemeine Java-Themen 2
D Mein Bäumchen Allgemeine Java-Themen 6
G JavaDocu in eigener Bibliothek Allgemeine Java-Themen 2
HarleyDavidson Eigener PropertyChangeListener funktioniert einfach nicht Allgemeine Java-Themen 3
T Datei öffnen mit eigener Applikation.exe Allgemeine Java-Themen 4
D Arraylist eigener Klasse an iReport übergeben Allgemeine Java-Themen 7
K Jar mit eigener JRE ausliefern Allgemeine Java-Themen 13
G eigener PropertyChangedListener Allgemeine Java-Themen 2
S OOP ClassCastException bei casting von eigener Klasse aus Iterator Allgemeine Java-Themen 3
V Serialisierung von Instanz eigener Klasse Allgemeine Java-Themen 5
N Vergleich eigener Klassen Allgemeine Java-Themen 5
T Vererbung Eigener Datentyp: Betriebsmittel Allgemeine Java-Themen 2
J Erste Schritte Kommerzielle nutzung eigener Javaapplets auf der Homepage Allgemeine Java-Themen 2
B Probleme mit eigener equals Methode Allgemeine Java-Themen 18
Kr0e Eigener Updatemechanismus Allgemeine Java-Themen 7
S Profiler-Funktionen in eigener Applikation nutzen..? Allgemeine Java-Themen 5
R Eigener Comparator Allgemeine Java-Themen 2
T Zeit von einem Server/Webseite auslesen und in eigener GUI anzeigen Allgemeine Java-Themen 6
V Probleme mit eigener Hashmap Allgemeine Java-Themen 10
B Eigener ClassLoader Allgemeine Java-Themen 9
R Eigener Assoziativ-Speicher Allgemeine Java-Themen 7
T CP Problem: Webstart + Logging properties file + eigener Handler Allgemeine Java-Themen 7
P eigener Klassenname Allgemeine Java-Themen 4
D Eigener Key bei AES Verschlüsselung Allgemeine Java-Themen 4
T enums - eigener startwert Allgemeine Java-Themen 5
J Eigener ClassLoader wird nicht immer verwendet Allgemeine Java-Themen 3
P eigener Thread für einen JButton Allgemeine Java-Themen 32
F Checkbox in JTable , eigener Cellrenderer -wie gehts weiter? Allgemeine Java-Themen 2
A JRE auf eigener Seite verlinken oder zum Download anbieten? Allgemeine Java-Themen 13
E Wie: Eigener Listener, eigenes Event (möglichst einfach) Allgemeine Java-Themen 29
G eigener logger mittels classe (dynamische logfilename) log4j Allgemeine Java-Themen 15
D Eigener Maven2 Plugin Server? Allgemeine Java-Themen 3
I RSA - Eigener Quelltext Allgemeine Java-Themen 4
M eigener LautstärkeRegler schädlich für soundkarte? Allgemeine Java-Themen 4
K JTree plus eigener FileLoader Allgemeine Java-Themen 2
L Problem mit eigener, abgeleiteter Klasse Allgemeine Java-Themen 2
S Eigener Editor Allgemeine Java-Themen 7
L Eigener Onlinestunden- Zähler / Problemchen Allgemeine Java-Themen 2
G Messenger bauen Allgemeine Java-Themen 4
D Messenger Allgemeine Java-Themen 11
R Instant Messenger Allgemeine Java-Themen 3

Ähnliche Java Themen

Neue Themen


Oben