Laden...

Netzwerk Protokoll - Basis

Erstellt von ClaraSoft vor 3 Jahren Letzter Beitrag vor 3 Jahren 1.297 Views
C
ClaraSoft Themenstarter:in
55 Beiträge seit 2020
vor 3 Jahren
Netzwerk Protokoll - Basis

Beschreibung:

Ja was soll ich sagen ursprünglich wollte ich eine Gui Anwendung mit einem Download/Patch Server programmieren. Geplant war das man über die Gui die ausgewählte aktuallisieren kann.
Beim implementieren der Netzwetkschnittstelle habe ich dann gemerkt, dass ich das meine Anwndung ein Protokol braucht, das auf TCP/UDP aufbaut, damit es kommunizieren kann. Wer hätte das gedacht...
Naja meine Idee zu dem Protokoll habe ich jetzt Github veröffentlicht. Dabei ist anzumerken, das ich das eher Snippet sehe und weniger als Projekt. Auch weil viele grundlegende Dinge noch fehlen bzw noch nicht implementiert sind:

-Security - fehlt bisher vollständig, Kommunikation ist unverschlüsselt

-Typ Validierung - der Header verwendet einen generischen Typ für den Message Typ(Type) das führt mit unterschiedlichen Implementationen zu fehlern - hier habe ich noch keine Idee wie ich das Problem lösen könnte.

Aufgrund dieser beiden Punkte möchte folgendes Klar stellen:
Diese Libary ist nicht für den Produktiveinsatz vorgesehen und sollte auch nicht in Produktivumgebungen eingesetzt werden.

Wer es dennoch tut ist selber schlud.

Was kann ich jetzt damit machen?
Meins kann als Basis zur Weiterentwicklung dienen. Dabei sollte man aber mindestens beiden oben genannten Punkte beachten.

Auf welches Protokoll kann ich aufbauen oder welchen Server kann ich nutzen?
TCP und UDP sollten gehen. Eventuell kann man auch auf Mqtt aufbauen oder auch eine Serielle Scnittstelle. Vielleicht findet auch jemand ein Anwendungsbereich als Websocket Protokoll. Wie auch immer mein Protokoll ist nur darauf ausgelegt byte Arrays zu Parsen und zu erstellen, die man von oder in Streams liest/schreibt, wie z.B. den NetworkStream.

Code:
https://github.com/SuperSaurfang/GenericNetworkProtocol

Ich würde über Anregungen freuen
Grüße

T
2.219 Beiträge seit 2008
vor 3 Jahren

Hab den code nur überflogen, sieht aber irgendwie sehr skurill aus.

Z.b. hast du keine richtiges Error Handling.
Wenn deine Parse Methoden aufgerufen werden, knallt es an allen Stellen wenn die Daten nicht passen.
Hier wäre es sinnvoll Fehlerfälle abzufangen also auch die Daten die du erhalten hast grundlegend zu validieren und eine entsprechende Exception zu werfen wenn diese nicht passen.
Deine "ProtocolLengthExecption" ist falsch geschrieben, Exception heißt das Wort. 😃

Was deine Protocol Klasse teilweise macht, sieht sehr magisch aus.
Du übergibst bei deinen Methoden UpdateLength und AddPayload die Instanz der Protocol Instanz um diese zu überschreiben und gibst diese dann per ref Parameter zurück.
Das ist alles andere als sinnvoll oder nötig.
Schau dir mal die Implementierung von List<T> an, dort wird bei Add /AddRange auch keine neue Instanz geliefert.
Protocol wäre hier auch m.M. der falsche Punkt.
Hier würde ich einen eigenen Container für die Daten anlegen.
Ggf. auch einfach auf List<T> zurückgreifen um die Bytes zu speichern.

Als Protokoll würde ich das auch (noch) nicht wirklich einstufen.
Du schiebst hier auch die grundlegende Übertragung der Daten wieder auf den Nutzer der Library zurück, da er diese über deine Protocol Klasse implementieren muss.
Wäre so als würde jemand ein Http Protokoll anbieten, ich müsste aber die eigentliche Datenübertragung mit TCP noch implementieren.

Was du hier anbietest ist eine Kapselung für die Daten, die man übertragen müsste.
Das funktioniert für sehr grundlegende Übertragungen via TCP/UDP.

Für fertige Protokolle wie Http/s oder MQTT würde ich deine Lib nicht nutzen.
Hier gibt es fertige Frameworks bzw. für MQTT mit MQTTnet auch eine sehr gute Lib, die schon alles fertige liefert.
Die jeweiligen Daten, die man dann übertragen muss, würde man auch wieder spezifisch implementieren, dafür braucht man keinen Overhead mit einer Protokoll Lösung.
Eine Einheitliche Lösung für alles, wie es dein Ansatz versucht, wird so nicht funktionieren bzw. nur bei spezifischen rudimentären Übertragungen.

Es fehlt auch eine Möglichkeit bei dem Protocol Daten für die Übertragung zu einem Client zu senden.
Wie würde da der Weg aussehen?
Aktuell hat deine Protocol Klasse nur ein GetBytes, was nur die Bytes holen würde.
Im Beispiel wäre dies einfach die Nachricht über Encoding.UTF8.GetBytes umzuwandeln.
Es gibt aber keine Möglichkeit die Daten für den Versand umzuwandeln.

Die ProtocolBase Klasse hat keine Implementierung, würde ich als Interface umsetzen und anbieten.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

5.657 Beiträge seit 2006
vor 3 Jahren

Das widerspricht der Idee des Projekte-Forums. Siehe dazu Lizenzbedingungen für die Projekte / Spezielle Regeln für Projekte-Threads:

In diesem Bereich soll der Nutzen der Leser deutlich im Vordergrund stehen und der Nutzen des Autors zurücktreten. Das Projekte-Unterforum ist also als Gelegenheit zu verstehen, der Community etwas (zurück) zu geben. Die geposteten Projekte sollte also möglichst fehlerfrei und sofort sinnvoll einsetzbar sein.

Der Beitrag wurde daher verschoben.

Weeks of programming can save you hours of planning

C
ClaraSoft Themenstarter:in
55 Beiträge seit 2020
vor 3 Jahren

Hallo T-Virus

Danke für dein Feedback. Du hast bei einigen Punkten Recht da besteht Verbesserungsbedarf, keine Frage. Ich gucke mal was ich wie Umsetze, besonders was Error Handling und das Parsen angeht.

Der Urprünglich von mir angedachte Einsatz Zweck war für TCP/UDP. Meine Aussage war eher als Anregung zu verstehen. Der User kann doch bisweilen sehr Kreativ werden. 😁

Also mein Gedanke war um die Daten versenden, war diese in einem Stream, z.B. die NetworkStream Klasse, zu schreiben. Da die Write und Read Methoden idr mit Byte Arrays aufgerufen werden, war es für mich logisch, dass meine Klassen Byte Arrays zurückgeben sollten.
Nachvollziehbar?

Ich habe noch ein paar Gedanken gemacht:
Sollte ich auf Serialisierung zurückgreifen?
Wie würdet ihr Verschlüsselung einbauen? Ich würde das ganze eher Flexibel haben wollen, damit selbst entscheiden kann was man nutzen möchte oder sollte ich das vorgeben?

Grüße

C
ClaraSoft Themenstarter:in
55 Beiträge seit 2020
vor 3 Jahren

Ich habe ein paar Änderungen durchgeführt. Unter anderem habe die AddPayload Methode umgeschrieben. Außerdem prüfe nun die länge des übergebens byte Arrays, ist dieses zu kurz werf ich eine exception. Ein zu kurzes Array kann gar nicht geparsed werden, da es nicht mal dem Header entsprechen kann... Bleibt nur das Problem, wie ich mit längenmässig validen und erfolgreich geparsten header umgehen, soll die trotzdem verkehrt sind. 🤔

/edit Ich habe das parsing der Enums für den Header etwas verbessert, Ich prüfe nun vorher mit IsDefined ob der Value überhaupt im Enum existiert.

T
2.219 Beiträge seit 2008
vor 3 Jahren

Beim überfliegen sind mir folgende Dinge aufgefallen.

1.In deiner Header Klasse hast du ein TryParse, was den geparsten Header liefert.
Ich würde hier eine Parse und eine TryParse Methode wie bei int anbieten.
Dann könnte man bei TryParse ein bool liefern, ob das parsen geklappt hat oder nicht und per out Parameter den geparsten Header.
Hier würde dann auch keine Exception geworfen.

Die Parse Methode würde den Header liefern aber dafür eine Exception werfen, wenn die Daten keinen gültigen Header liefern.

2.Deine Protocol Klasse hat eine CreateHeader Methode, die aber Protocol<T> liefert.
Der Methoden Name würde mir auf den ersten Blick eher sugerieren, dass ich eine Header Instanz bekomme.
Ggf. sollte der Name der Methode klarer gewählt werden, damit klar wird das man eine neue Instanz von Protocol nur bestehend aus einem Header bekommt.

3.Die Parse Methode in Protocol bekommt ein Byte Array data und ein PayloadBase.
Sollten die Daten nicht vollständig im byte Array stehen?
Wozu gibt es hier noch ein PayloadBase Parameter.
Ich würde hier erwarten, dass ich einfach den Byte Block an die Methode gebe und den Header + Payload ausgelesen bekomme.

4.AddPayload sieht immer noch komisch aus.
Du überschreibst dabei die Instanz des aktuellen Payloads aber vergrößerst die Länge im Header.
Wenn ich AddPayload also mehrfach aufrufe mit kleinen Payload Blöcken für das selbe Paket, würde n dann im Header nicht mehr Daten sehen als ich liefere?
Sinnvoller wäre es im Protocol eine Liste von Payloads zu haben oder die Payloads zu einem Block zusammen zu schieben.

5.Es wäre sinnvoll, damit du effektiv Fehler im Code findest, auch UnitTests anzulegen.
Das spart dir zukünftig beim entwickeln bei Änderungen viel Arbeit/Zeit bei der Suche nach Fehlern.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.