CS_LEVEL_20_SOLUTION - OnlyCook/abitur-elite-code GitHub Wiki
Level 20 – Musterlösung: Smart Home Hub (Verbindungsaufbau)
Lösung
public class SmartHomeServer
{
private int port;
private ServerSocket server;
public SmartHomeServer(int port)
{
this.port = port;
this.server = new ServerSocket(port);
}
public void StartServer()
{
Socket clientSocket = server.Accept();
clientSocket.Write("+OK Smart Home Hub\n");
string befehl = "";
while (befehl != "QUIT")
{
befehl = clientSocket.ReadLine();
if (befehl.StartsWith("HELLO:"))
{
string id = befehl.Substring(6);
clientSocket.Write("+ACK " + id + "\n");
}
else if (befehl != "QUIT")
{
clientSocket.Write("-ERR unbekannt\n");
}
}
clientSocket.Close();
}
}
Erklärung
Willkommen in Sektion 5
Ab jetzt dreht sich alles um das Client-Server-Prinzip – ein zentrales Thema im Hessischen Abitur. Statt komplexe Algorithmen zu entwickeln, liegt der Fokus hier darauf, einen vorgegebenen Kommunikationsablauf präzise in Code zu übersetzen. Ein Werkzeug dafür ist oft das Sequenzdiagramm.
Das Sequenzdiagramm lesen
Ein Sequenzdiagramm zeigt, in welcher Reihenfolge Objekte miteinander kommunizieren. Jedes Objekt hat eine vertikale Linie (Lebenslinie), Pfeile zwischen diesen Linien stellen Methodenaufrufe dar. Die Zeit läuft von oben nach unten.
Die wichtigsten Elemente in diesem Level:
loop: Eine Schleife – hier läuft die Kommunikation so lange, bisbefehl != "QUIT".alt/else: Eine Verzweigung – entspricht einemif/else ifim Code.
Das Sequenzdiagramm ist die Blaupause; der Code soll diesen Ablauf exakt widerspiegeln.
Der Konstruktor
public SmartHomeServer(int port)
{
this.port = port;
this.server = new ServerSocket(port);
}
Der Konstruktor speichert den Port und erstellt direkt ein ServerSocket-Objekt. Im Klassendiagramm ist server als Assoziationsattribut eingetragen – es wird also als Attribut der Klasse gehalten und im Konstruktor initialisiert.
StartServer() – das Sequenzdiagramm umsetzen
Schritt 1: Verbindung annehmen
Socket clientSocket = server.Accept();
Accept() blockiert, bis ein Client die Verbindung aufbaut, und gibt dann einen Socket zurück. Über diesen Socket läuft die gesamte weitere Kommunikation mit dem Client – er ist quasi der „Kanal" zum Client.
Schritt 2: Begrüßung senden
clientSocket.Write("+OK Smart Home Hub\n");
Der Server meldet sich direkt nach dem Verbindungsaufbau beim Client. Das \n am Ende ist ein Zeilenumbruch – im Netzwerkprotokoll signalisiert er dem Client, dass die Nachricht vollständig ist.
Schritt 3: Die Befehlsschleife
string befehl = "";
while (befehl != "QUIT")
{
befehl = clientSocket.ReadLine();
// ...
}
Die Schleife liest Befehle, solange der Befehl nicht "QUIT" ist. befehl wird vor der Schleife mit "" initialisiert, damit die Bedingung beim ersten Durchlauf nicht sofort greift. ReadLine() wartet auf eine vollständige Zeile vom Client.
Schritt 4: Die Verzweigung
if (befehl.StartsWith("HELLO:"))
{
string id = befehl.Substring(6);
clientSocket.Write("+ACK " + id + "\n");
}
else if (befehl != "QUIT")
{
clientSocket.Write("-ERR unbekannt\n");
}
Hier werden zwei neue String-Methoden eingesetzt:
StartsWith(string prefix) prüft, ob ein String mit einem bestimmten Text beginnt. "HELLO:Device1".StartsWith("HELLO:") ergibt true.
Substring(int startIndex) schneidet einen Teilstring aus. Der Index gibt an, ab welcher Stelle (0-basiert) der neue String beginnt – alles davor wird weggelassen. "HELLO:" hat 6 Zeichen (H, E, L, L, O, :), also liefert Substring(6) alles ab Position 6, also die ID.
"HELLO:Device1"
0123456
^^^^^^^ → "Device1"
Der else if-Zweig prüft zusätzlich, ob der Befehl nicht "QUIT" ist – denn QUIT soll keine Fehlermeldung auslösen, sondern nur die Schleife beenden.
Schritt 5: Socket schließen
clientSocket.Close();
Nach dem Verlassen der Schleife wird die Verbindung sauber beendet. Das entspricht exakt dem letzten Pfeil im Sequenzdiagramm.