Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Empfohlene Antworten

Veröffentlicht

Schönen guten Abend euch,

derzeit arbeite ich an einer Client/Server Lösung.

Der Server überträgt dem Client Daten aus einer Mysql Datenbank, evtl. auch Dateien.

Meine Frage ist jetzt, wie würde dafür ein relativ sauberes Protokoll aussehen?

Ich habe es mir so gedacht:

Der Client bekommt immer mindestens ein Paket zugeschickt, das wie folgt aussieht:

ID#Type#MaxCountPackets#CurrentCountPackets#Data

ID: die ID des Paketes (Die ID ist in jedem "Subpaket" gleich)

Type: sagt dem Client, ob es sich um eine Datei, um einen String o.ä handelt

MaxCountPackets: Wie viele Subpakete es gibt, falls Data größer als 4096 Byte ist

CurrentCountPackets: sagt um welches SubPaket es sich handelt

Data: kann alles mögliche sein (String, Logindaten, Bilder...)

Dieser String wird dann immer mit einer Raute gesplittet.

Wenn Data größer als 4096 Byte ist, wird ein zweites Paket hinterher geschickt.

Frage 1: Ist dies eine akzeptable Möglichkeit, um eine Cient/Server Kommunikation aufzubauen?

Frage 2: Kann ich dann einfach die komplette Nachricht am TCP Client entgegennehmen? Das heißt, dass ich keinen Buffer dazwischen schalten muss, da der Buffer eigentlich schon in der Nachricht enthalten ist.

Frage 3: Ist der Buffer, bzw. die maximale Länge pro Paket von Data zu groß?

Wenn du sicherstellen kannst, dass in keinem Block eine weitere Raute vorkommen kann und du somit eine feste Anzahl an Trennzeichen hast, müsste es gehen. Wenn du das nicht sicherstellen kannst (wenn du zum Beispiel den Data Teil text sendest und dieser auch Rauten enthalten kann), kannst du nicht mit Sicherheit bestimmen, wann ein Paket zuende ist.

In diesem Fall solltest du ein anderes Zeichen für Start und Ende verwenden.

Bearbeitet von Shadowman

  • Autor
Wenn du sicherstellen kannst, dass in keinem Block eine weitere Raute vorkommen kann und du somit eine feste Anzahl an Trennzeichen hast, müsste es gehen. Wenn du das nicht sicherstellen kannst (wenn du zum Beispiel den Data Teil text sendest und dieser auch Rauten enthalten kann), kannst du nicht mit Sicherheit bestimmen, wann ein Paket zuende ist.

In diesem Fall solltest du ein anderes Zeichen für Start und Ende verwenden.

Was gibt es dann for ASCII Zeichen, die kaum benutzt werden. Ich kann nämlich nicht sicherstellen, was für Zeichen Data enthält.

Edit: Was haltet ihr von einer Reihe von Zeichen wie {#}?

Hast du eine bessere Idee?

Du könntest eine Escape-Sequenz benutzen, wenn im Datenstrom ein Steuerzeichen (in deinem Fall #) auftritt. Beispielsweise könntest du das Steuerzeichen verdoppeln, wenn es als Teil der Daten und nicht als Steuerzeichen interpretiert werden soll.

Oder du baust die Länge der Nachricht mit ins Protokoll ein.

Standard Ascii Codes mit Bedeutung:

0x01 -> Start of Header

0x02 -> Start of Text

0x03 -> End of Text

0x04 -> End of Transmission

so würde ich es aufbauen:

0x01ID#Type#MaxCountPackets#CurrentCountPackets0x02Data0x030x04

Das wäre glaube ich am saubersten

Bearbeitet von Shadowman

  • Autor
Das verlagert das Problem nur. Was machst du, wenn diese Byte-Folge in deinen Nutzdaten auftaucht?

Eben, dass kann ich leider nichts sicherstellen. Okay ich denke da werde ich die Länge von Data mit ins Protokoll nehmen.

Also so:

#ID#Type#MaxCountPackets#CurrentCountPackets#DataLength#Data#

Das ist ja toll, wenn man Texte überträgt. Aber sobald man Binärdaten hat, hilft das auch nicht weiter.

Wenn er Binärdaten überträgt, im Data-Block aber Text kommt (Zitat Repac3r: Ich kann nämlich nicht sicherstellen, was für Zeichen Data enthält.) muss er diese ja sowieso umwandeln. Somit muss er eine Konvertierungsmethode implementieren um aus dem Text einen Binärsatz zu machen.

Wenn er die Codes vor der Konvertierung anfügt und mit Konvertiert (natürlich dann auch umgekehrt bei der Verarbeitung) kann er auch beim eintreffen des Datenstroms auf diese Werte (natürlich binär) prüfen.

Wenn jetzt das Argument kommt, dass diese Zeichenkombination immer vorkommen kann: Jede binäre Kombination könnte rein Theoretisch in einer Folge auftreten. Hier geht es doch lediglich darum die Warscheinlichkeit zu reduzieren (oder liege ich da falsch?)

Mit Datentransfer habe ich mich noch nicht so tiefgehend auseinandergesetzt

  • Autor
Somit muss er eine Konvertierungsmethode implementieren um aus dem Text einen Binärsatz zu machen.

Muss ich eigentlich nicht machen, da ich ja bei Type angebe, um was es sich handelt (Text, Binär).

Somit muss er eine Konvertierungsmethode implementieren um aus dem Text einen Binärsatz zu machen.
Unsinn. Textdaten sind immer Binärdaten, umgekehrt nicht.

Wenn jetzt das Argument kommt, dass diese Zeichenkombination immer vorkommen kann: Jede binäre Kombination könnte rein Theoretisch in einer Folge auftreten. Hier geht es doch lediglich darum die Warscheinlichkeit zu reduzieren (oder liege ich da falsch?)
Wenn das Funktionieren des Protokolls auf Wahrscheinlichkeiten beruht, ist es kaputt. Es gibt erprobte Lösungen für dieses Problem, und ich habe sie genannt.
  • Autor
Welchen Sinn hat es ein eigenes Protokoll zu entwerfen? Im Normalfall sollte man auf bestehende Protokolle aufsetzen, als das Rad neu zu erfinden.

Deswegen habe ich auch gefragt, ob es bessere Möglichkeiten gibt :)

Und zur "immer wieder Rad neu erfinden Geschichte", mir macht es Spaß zu programmieren und Probleme zu lösen. ;)

  • Autor

Eine Escapesequenz hat ja wieder das selbe Problem (sie könnte zufällig im Datenstrom auftauchen)

Habe das Problem gelöst, indem ich einfach die Länge von Data mit ins Protokoll nehme.

Aber wie würdet ihr solch eine Kommunikation aufbauen?


"CLIENT"


Client.WriteByte(MSGTYPE type BYTE)

Client.WriteInt(MSGLEN type INT)

Client.WriteStream(MSG,MSGLEN)


Client -> Request.Send();


-------------------

"SERVER"

if(Server.Receive())

{

MSGType as Byte = Server.ReadByte(MSGTYPE type BYTE)

MSGLen as Byte = Server.ReadInt(MSGLEN type INT)

MSG as <2string>Stream Client.ReadStream(MSGLEN)

}

Protokollbescheibung:

-1 Byte MSG Type

-1 Int(4 Byte je nach Plattform/Compiler, wobei ich 2 Byte eher als Short betrachte) Länge der Nachricht

-Nachricht.

Warum nur einen String senden und den Aufwendig parsen? Wenn das viel viel einfacher geht ;) !

Wenn der Server seine Antworten im Selben Schema (Protokoll) sendet, kannst du eine Methode implementieren zum senden und lesen die vom Host und Clienten benutzt werden kann. (U.a. Sinn und Zweck solcher Protokolle ein Verbindliches/Einheitliches Kommunikationsschema.)

Habe schon hochskalierbare Client/Host Protokolle implementiert (Slotbasierte Kommunikation etc. .....).

Nach eigenen Vorstellungen erweiter- und modifizierbar.

Sollte als Denkanstoß passen/genügen ;) ! Toi Toi Toi und viel Erfolg!

Gruß

Patrick

Bearbeitet von Patrick_C64

Erstelle ein Konto oder melde dich an, um einen Kommentar zu schreiben.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.