Ich musste heute zunächst erst einmal erschrocken feststellen, dass es vor der Prüfung heute unsere letzte Vorlesung war. Ich war die ganze Zeit noch der Überzeugung, dass noch eine Vorlesung kommt. Durch den Zeitdruck, dass es heute die letzte Vorlesung war, ging es nach der zunächst sehr locker angefangen Vorlesung ziemlich im Marschtempo weiter. Besser gesagt, wir sind an manchen Stellen schneller über die Folien, als der Millenium Falke in Star Wars. Dennoch habe ich versucht immer hinter her zu bleiben, auch wenn meine WLAN Verbindung mir zum Schluss einen Strich durch die Rechnung gemacht hatte und ich dann nur noch einen schwarzen Bildschirm hatte, zwar mit Ton, aber auf die Folie konnte ich währenddessen keinen Blick mehr werfen. Aber, fangen wir doch mal am Beginn der Stunde an.
Am Anfang der Stunde hatten wir kurz darüber geredet, dass in 2 Wochen die Prüfung ansteht. Innerlich fing dann bei mir die Panik an, dass ich es dieses Mal zwar wirklich gut verstanden und die Aufgaben auch ohne Probleme gut lösen konnte, aber ob mein Portfolio denn von der Menge ausreichen würde. Was mir später erst wieder bewusst wurde war, dass wir letztes Semester wesentlich mehr Vorlesungen hatten und auch weniger Aufgaben und somit mehr Vorlesungszeit hatten.
Nachdem das mit der Prüfung ein wenig in de Hintergrund rückte, gingen wir ein wenig detaillierter auf den Chat Client von der letzter Vorlesung ein, was mir sehr geholfen hatte, denn ich war ja wie bereits erwähnt nicht die ganze Vorlesung anwesend.
Hier noch einmal der Code für den einfachen Chat Server gefolgt von dem des Chat Clients (schon inkl. den Lösungen der Aufgabe, aber auf diese werde ich später noch einmal eingehen):


Diesen Server sollten wir aus einer txt Datei von Herr Noll abschreiben und anschließend dann den Client (wie schon gesagt sind die Lösungen bereits enthalten, aber auskommentiert):



Wie man also sehen kann, ein ganz schön langer Code. Glücklicherweise, musste man nur den Client abschreiben, den Server konnte man kopieren und einfach in Eclipse ausführen. Ohne die erfüllte Aufgabe kommt dann folgende Ausgabe:

Nun kurz zu der Aufgabe, bevor ich auf den Code ein wenig detaillierter eingehen werde. Die Aufgabe war wie folgt:
- Chat Client abschreiben
- ServerCode von ihm abschreiben bzw. kopieren
- Testen
- Erweiterung einbauen: Text absenden mit Enter Taste (also ohne auf den Button klicken zu müssen) und Eigenen Namen bei ausgehender Nachricht davor schreiben
Wie oben gezeigt, ist also 1 bis 3 schon einmal abgehakt 🙂 Gehen wir auf den 4. Punkt ein. Um das mit der Enter Taste abschicken zu können, braucht man einen Key-, oder Action Listener. Wie man bei den Imports schon sehen kann, sind die benötigten Packages für den Event und KeyListener schon implementiert (java.awt.event, java.awt). Da es sich bei der Enter Taste aber um ein keyboard Event handelt, habe ich den KEYListener genommen. Ein Key-Event wird erzeugt, wenn eine Taste gedrückt, losgelassen oder getippt wird, also in unserem Falle die Enter-Taste. Dann wird die entsprechende Methode im Listener-Objekt aufgerufen, und das KeyEvent wird an dieses übergeben.
Nun zur Erklärung des Codes inklusive den Lösungen, denn beim Schreiben bemerke ich dass es so mehr Sinn ergibt, auch für mich, um es noch einmal nachzuvollziehen. Auf den Server werde ich nicht mehr eingehen, denn das hatte ich innerhalb des letzten Eintrags schon ausführlich erwähnt.
In den ersten Zeilen des Client Codes werden die benötigten packages implementiert. Die ersten beiden, also io und net, sind für die Client/Server Verbindung zuständig. Swing ist ein GUI Toolkit, genauso wie auch java.awt. Java.awt.event stellt Schnittstellen und Klassen für den Umgang mit verschiedenen Arten von Ereignissen zur Verfügung, die von AWT-Komponenten ausgelöst werden. Ein wenig weiter unten folgt dann die GUI, auf die ich letzte Vorlesung auch schon detailliert eingegangen bin. Jedoch wurde mir beim öfteren Durchlesen bewusst, dass eingehend und ausgehend hier erst deklariert werden. Eingehend ist die TextArea mit der Größe 15 auf 20, ausgehend ist das TextField mit der Länge 20. Auch wurde mir hier wieder besser bewusst, was es mit dem .add auf sich hat in Zeile 32. Hier wird dem SendenButton der ActionListener hinzugefügt mit der Klasse SendenButtonListener, die weiter unten im Code vorkommt. Diese Klasse sorgt sich darum, dass wenn der Benutzer auf den Button klickt, dass dann die Methode den Inhalt des Textfelds an den Server sendet. Um die Aufgabe zu lösen, musste man bei ausgehend noch einen KeyListener hinzufügen. KeyListener ist ein Interface, welches wie gesagt dafür zuständig ist, Keyboard Events zu erhalten. Unten wurde deshalb noch eine neue Klasse SendenKeyListener hinzugefügt, die das Interface implementiert. Diese Klasse enthält die Methode, die dafür sorgt, dass wenn Enter gedrückt wird, das dann annick (also mein Name :D) und der ausgehende Text ausgegeben werden.
Hier noch einmal die Änderungen, die ich vorgenommen hatte:


Wenn ich nun zuerst den Server und dann den Client laufen lasse, kommt folgendes:

Es scheint sich also nichts getan zu haben.
Wenn ich nun jedoch eine Nachricht eine Nachricht eingibt und Enter drückt, dann:

Es hat also funktioniert!
Danach kam noch einmal eine kleine Wiederholung des Erzeuger Verbraucher Problems. Ich hatte zwar letzte Woche schon einmal drüber geschrieben, jedoch sind wir noch einmal ausführlicher darauf eingegangen, weshalb ich es noch einmal benenne. Hier war ja das Problem der Nebenläufigkeit, bzw. Probleme die bei der Synchronisation aufkommen können, denn der Erzeuger produzierte zwar die Werte 0 bis 4 in der richtigen Reihenfolge, jedoch hat der Verbraucher einige Werte mehrfach bzw. überhaupt nicht entnommen. Deshalb, muss man schauen, dass der Verbraucher nur dann aktiv wird, wenn der Erzeuger wieder einen neuen Wert bereitgestellt hat. Also müssen die beiden Threads irgendwie miteinander kommunizieren. Her Noll hatte es heute, wie auch letzte Woche mit Netflix verglichen, nur dass das dann noch ein Stück komplizierter ist. Bei Netflix wird jedoch kein Wert gepfuffert, sondern der Stream und der Verbraucher ist die Streaming-Software beim Benutzer. In folgendem Code, bei dem das oben genannte Problem gelöst wird, wird nur ein Wert gepuffert:

Immer einer der Threads schreibt (Erzeuger) und der andere liest (Verbraucher).
Das ganze sieht bildlich so aus:

Es wird kein join verwendet, da die Threads ja abwechselnd laufen sollen und nicht erst der eine und dann der andere. Durch das wait() wird der aktuelle Thread dazu gebracht zu warten, bis der andere ein notify() bringt. Dadurch, dass ein flag, auch Semaphor genannt (wusste ich bis jetzt auch nicht), wird das Problem vorgebeugt, dass es zu Problemen kommen könnte, denn ein flag ist eine boolesche Variable, mit der man einen Zustand speichert. Am Anfang ist verfuegbar false, denn anfangs ist ja kein Wert da, den man auslesen kann. Wenn Nichts drin ist, wird also kein get ausgeführt, sondern gewartet. Falls verfuegbar true ist, wird ein notify() aufgerufen, damit der Verbraucher den Wert abholen kann. Wenn man aber wie gesagt nur der flag weglässt, dann kann das ganze auch zu einer Deadlock Situation kommen, denn die beiden Threads sind ja voneinander abhängig und können sich gegenseitig blockieren.
Gleich geht es weiter mit dem zweiten Teil der Vorlesung, jedoch ist das ein anderes Thema und liegt somit in einem anderen Verzeichnis, jedoch machte ich mir während der Pause bzw. nachdem ich mit der Aufgabe fertig war noch ein paar Gedanken zu meinem Schwerpunktthema. Dieses Mal finde ich es wirklich ein wenig schwer mir was passendes auszudenken. Die Möglichkeiten sind alles mögliche zu asynchrone Kommunikation, node.js, Angular, verteilte Systeme und Netzwerkkommunikation. Dabei ist mir aufgefallen, dass ich sogar bereits mit node.js und npm, also dem package manager gearbeitet hatte, es aber komplett vergaß. Node.JS ist ein Open-Source JavaScript Laufzeitumgebung, bei der JavaScript serverseitig ausgeführt wird. JavaScript wird eigentlich nur auf dem Client, also in Ihrem Webbrowser ausgeführt, um bestimmte Aktionen auszuführen. Node.JS dreht das Prinzip um und führt den JavaScript-Code auf dem Server aus, schon bevor die Daten zum Client gesendet werden. Es ist also zur dynamischen Web- Entwicklung gedacht. npm ist ein Paketmanager für Node.js und wird automatisch mit node mitinstalliert. Außerdem hat es eine Kommando Zeile, mit der man einiges steuern kann.
Außerdem hatte eine meiner Kommilitonen ARP genannt gehabt. Das hatten wir in einer der IT Vorlesungen. Dies ist ein Netzwerkprotokoll, das zu einer Netzwerkadresse der Internetschicht die physische Adresse (Hardwareadresse) der Netzzugangsschicht ermittelt und diese Zuordnung gegebenenfalls in den ARP-Tabellen der beteiligten Rechner hinterlegt. Jedoch kann ich mich auch noch daran erinnern, dass das nicht ganz sicher war und man ARP Spoofing betrieben konnte. Das heißt, dass der Angreifer seine eigene MAC-Adresse als die eines anderen Endgeräts ausgibt und somit alle Pakete an ihn und nicht an den eigentlichen Empfänger gesendet werden. ARP-Spoofing ist allerdings nur dann möglich, wenn sich der Angreifer im selben lokalen Netzwerk befindet.
Meine weiteren Ideen, was ich als Schwerpunkt nehmen könnte:
- Python, da es häufig für serverseitige Entwicklung genutzt wird und ich selbst schon mit Python programmiert habe
- Vue.js, es ist zwar clientseitig, aber man kann für die asynchrone Entwicklung u.A. auch await und promises benutzen und mit vue.js hatte ich auch schon gearbeitet
- Public key Kryptographie, da das für Netzwerkkommunikation ziemlich wichtig ist und ich mag das Thema Kryptographie wirklich sehr
- Dann wäre mir als Entwicklungsumgebung noch Visual Studio Code eingefallen, denn ich arbeite sehr gerne damit, da das dort ja alles in Komponenten aufgeteilt und somit sehr ordentlich und übersichtlich ist.
- ECMAScript6, auch JavaScript 6 genannt
So das war es dann mit dem ersten Teil. Der Zweite folgt gleich und wird sich um PHP drehen.