Diese Implementierung demonstriert das State Pattern anhand einer TCP-Verbindungssimulation. Das Projekt zeigt, wie man zustandsabhängiges Verhalten effektiv organisieren und verwalten kann.
- Simulation der wichtigsten TCP-Verbindungszustände
- Interaktives Menü zur Steuerung der Verbindung
- Farbige Konsolenausgabe für bessere Übersicht
- Statistik-Tracking für Verbindungsaktivitäten
- Implementierung des State Patterns
- Fehlerbehandlung für ungültige Zustandsübergänge
- Klone das Repository:
git clone https://github.com/goljunge91/tcp-state-pattern.git
- Wechsle in das Projektverzeichnis:
cd tcp-state-pattern
- Kompiliere das Projekt:
mkdir build
cd build
cmake ..
make
Starte das Programm:
./tcp_state_machine
ACTIVEOPEN
: Aktiver VerbindungsaufbauPASSIVEOPEN
: Passiver VerbindungsaufbauSEND
: Daten sendenCLOSE
: Verbindung schließenACK
: Bestätigung sendenSYNC
: Synchronisation durchführenOCTET
: Text-Daten sendenSHOWSTATE
: Aktuellen Zustand anzeigenSHOWSTATS
: Statistiken anzeigenMENU
: Menü anzeigenEXIT
: Programm beenden
TCPConnection
: Hauptklasse für die VerbindungsverwaltungTCPState
: Abstrakte Basisklasse für alle ZuständeTCPClosed
: Implementierung des geschlossenen ZustandsTCPListen
: Implementierung des Listen-ZustandsTCPEstablished
: Implementierung des etablierten Zustands
src/
├── TCPConnection.h/cpp # Hauptklasse
├── TCPState.h/cpp # Abstrakte Zustandsklasse
├── states/ # Konkrete Zustandsimplementierungen
│ ├── TCPClosed.h/cpp
│ ├── TCPListen.h/cpp
│ └── TCPEstablished.h/cpp
├── TCPOctetStream.h/cpp # Datenstream-Implementierung
└── Menu.h/cpp # Menü-System
Das Projekt verwendet das State Pattern mit folgenden Komponenten:
-
Context (TCPConnection)
- Verwaltet den aktuellen Zustand
- Delegiert zustandsspezifische Anfragen
-
State (TCPState)
- Definiert die Schnittstelle für zustandsspezifisches Verhalten
- Implementiert Standardverhalten
-
Concrete States
- TCPClosed: Initialzustand
- TCPListen: Wartet auf Verbindungen
- TCPEstablished: Aktive Verbindung
Das System kann einfach um weitere Zustände erweitert werden:
- Erstelle neue Zustandsklasse
- Erbe von TCPState
- Implementiere erforderliche Methoden
- Füge Zustandsübergänge hinzu
#ifndef TCPWAITING_H
#define TCPWAITING_H
#include "../TCPState.h"
class TCPWaiting : public TCPState {
public:
// Überschreiben der relevanten Methoden
void Acknowledge(TCPConnection* connection) override;
void Close(TCPConnection* connection) override;
void Send(TCPConnection* connection) override;
// Name des Zustands
string GetName() const override {
return "WAITING";
}
};
#endif
#include "TCPWaiting.h"
#include "../TCPConnection.h"
#include "TCPEstablished.h"
#include "TCPClosed.h"
#include <iostream>
void TCPWaiting::Acknowledge(TCPConnection* connection) {
std::cout << "\033[32mAcknowledge empfangen, wechsle zu ESTABLISHED\033[0m\n";
ChangeState(connection, new TCPEstablished());
}
void TCPWaiting::Close(TCPConnection* connection) {
std::cout << "\033[31mVerbindung wird geschlossen\033[0m\n";
ChangeState(connection, new TCPClosed());
}
void TCPWaiting::Send(TCPConnection* connection) {
std::cout << "\033[33mSenden im WAITING-Zustand nicht möglich\033[0m\n";
ChangeState(connection, new TCPClosed());
}
// ## TCPEstablished
void TCPEstablished::Send(TCPConnection* connection) {
if(sendBuffer_.size() >= windowSize_) {
std::cout << "\033[33m[Warning] Sendefenster voll. Warte auf ACKs...\033[0m\n";
ChangeState(connection, new TCPWaiting()); // Wechsel zu WAITING wenn Buffer voll
return;
}
connection->IncrementPacketCount(); // Erhöhe Paketzähler
std::cout << "\033[32m[Send] Bereit für neue Datenübertragung\033[0m\n"
<< "Aktuelles Fenster: " << sendBuffer_.size() << "/" << windowSize_ << "\n";
// Optional: Wechsel zu WAITING nach erfolgreichem Senden
if(sendBuffer_.size() > windowSize_ / 2) { // Beispiel: Wechsel wenn Buffer mehr als halb voll
std::cout << "\033[33m[Info] Buffer wird voll, wechsle zu WAITING...\033[0m\n";
ChangeState(connection, new TCPWaiting());
}
}
-
Problem: Ungültiger Zustandsübergang
- Lösung: Prüfen Sie den aktuellen Zustand mit
SHOWSTATE
- Lösung: Prüfen Sie den aktuellen Zustand mit
-
Problem: Verbindung reagiert nicht
- Lösung: Verwenden Sie
SHOWSTATS
zur Diagnose
- Lösung: Verwenden Sie
- Fork das Projekt
- Erstelle einen Feature Branch
- Committe deine Änderungen
- Push zu dem Branch
- Erstelle einen Pull Request
Dieses Projekt ist unter der MIT-Lizenz lizenziert. Weitere Details finden Sie in der LICENSE-Datei.
Marco Tozzi - GitHub