Frage

Ich bin ein Spiel-Server entwerfen und ich habe noch nie etwas getan. Ich habe mich nur gefragt, was eine gute Struktur für eine Paketdaten-weise wäre? Ich verwende TCP, wenn es darauf ankommt. Hier ist ein Beispiel, und was ich in Anbetracht wurde mit ab jetzt:

(jeder Wert in Klammern ist ein Byte)

[Packet length][Action ID][Number of Parameters]
[Parameter 1 data length as int][Parameter 1 data type][Parameter 1 data (multi byte)]
[Parameter 2 data length as int][Parameter 2 data type][Parameter 2 data (multi byte)]
[Parameter n data length as int][Parameter n data type][Parameter n data (multi byte)]

Wie ich schon sagte, ich habe wirklich nie etwas getan, bevor so, was ich oben habe kompletter Stier sein könnte, weshalb ich frage;). Außerdem wird das Bestehen der Gesamtpaketlänge sogar notwendig?

War es hilfreich?

Lösung

die Gesamtpaketlänge Passing ist eine gute Idee. Es könnte zwei weitere Bytes kosten, aber Sie können für die Steckdose peek und warten bereit vor dem Empfang schlürfen ein vollständiges Paket zu haben. Das macht Code einfacher.

Insgesamt stimme ich brazzy, eine Sprache geliefert Serialisierungsmechanismus ist preferrable über jeder sich selbst gemacht.

Anders als das (ich glaube, Sie sind eine C-ish Sprache ohne Serialisierung verwendet wird), würde ich die Paket-ID als die ersten Daten über die Paketdatenstruktur setzen. IMHO das ist eine Art von Konvention, weil das erste Datenelement einer Struktur immer an Position 0 und jede Struktur kann, dass die Identifizierung ansonsten anonyme Daten gesenkten sein.

Ihr Compiler oder lassen sich möglicherweise nicht gepackten Strukturen, aber auf diese Weise können Sie einen Puffer zuweisen, lesen Sie das Paket in und dann entweder die Struktur gegossen auf dem ersten Datenelement abhängig. Wenn Sie kein Glück, und es erzeugt keine gepackten Strukturen, sollten Sie eine Serialisierung Methode für jede Struktur haben, die von den (offensichtlich nicht Ziel) Speichern konstruieren wird.

Byte-Reihenfolge ist ein Faktor, vor allem auf C-ähnlichen Sprachen. Achten Sie darauf, deutlich zu machen, dass Pakete derselben endianness sind immer oder dass Sie einen anderen Endian basiert auf einer Signatur oder etwas erkennen kann. Eine seltsame Sache, die sehr cool: C # und .NET scheinen immer Daten in Little-Endian-Konvention zu halten, wenn Sie sie wie hier in diesem Beitrag diskutiert mit zuzugreifen. Festgestellt, dass, wenn eine solche Anwendung Portierung auf einer SUN auf Mono. Cool, aber wenn Sie, dass das Setup haben, sollten Sie die Serialisierung mittels C # sowieso verwenden.

Other than that, Ihr Setup sieht sehr okay!

Andere Tipps

Starten Sie durch einen viel einfacheren Grund Wrapper Berücksichtigung Tag, Länge, Wert (TLV). Ihr Basispaket sieht dann wie folgt aus:

[Tag] [Length] [Value]

Tag ist eine Paketkennung (wie Ihre Aktions-ID).

Länge ist die Paketlänge. Sie können diese müssen sagen, ob Sie das volle Paket haben. Es wird Ihnen auch lassen, herauszufinden, wie lange der Wertebereich ist.

Wert enthält die eigentlichen Daten. Das Format dieser kann alles sein.

In Ihrem Fall oben enthalten die Wertdaten eine weitere Reihe von TLV Strukturen (Parameter Typ, Länge, Wert). Sie nicht wirklich brauchen, um die Anzahl der Parameter zu senden, wie Sie es von der Datenlänge arbeiten kann und die Daten gehen.

Wie bereits gesagt wurde, würde ich die Paket-ID setzen (Tag) aus. Es sei denn, Sie plattformübergreifende Interessen haben, würde ich prüfen, Ihre Anwendung serialisierte Objekt in einem TLV Einwickeln und es über den Draht wie das Senden. Wenn Sie einen Fehler machen oder später ändern möchten, können Sie immer einen neuen Tag mit einer anderen Struktur erstellen.

Weitere Details finden Wikipedia TLV .

Um zu vermeiden, das Rad neu zu erfinden, wird jede Serialisierung Protokoll für die Arbeit an den Drahtdaten (zB XML, JSON), und man könnte betrachten unter BEEP für das Basisprotokoll-Framework.

BEEP ist in seiner FAQ-Dokument als ‚ eine Art‚beste Treffer‘Album der von erfahrenen Anwendungsprotokoll Designer seit den frühen 80er Jahren. verwendet Tricks‘

aufsummiert

Es gibt keinen Grund, etwas zu machen, so wie das kompliziert. Ich sehe, dass Sie eine Aktion ID, so dass ich nehme an, es würde eine feste Anzahl von Aktionen sein.

Für jede Aktion würden Sie eine Datenstruktur, definieren und dann würden Sie jeden dieser Werte in der Struktur setzen. Um es über den Draht zu senden, ordnen Sie nur sum (sizeof (struct.i)) Bytes für jedes Element in Ihrer Struktur. Also Ihr Paket würde wie folgt aussehen:

[action ID][item 1 (sizeof(item 1 bytes)][item 1 (sizeof(item 2 bytes)]...[item n (sizeof(item n bytes)]

Die Idee ist, Sie wissen schon, die Größe und Art der einzelnen Variablen auf jeder Seite der Verbindung ist, so brauchen Sie nicht, dass die Informationen zu senden.

Für Strings, können Sie einfach werfen ‚em in einem Null-in beendet Form, und dann, wenn Sie‚weiß‘für einen String auf dem Pakettyp basierte zu suchen, zu lesen beginnen und auf der Suche nach einem null.

-

Eine andere Möglichkeit wäre, zu verwenden ‚\ r \ n‘ Ihre Variablen zu beschreiben. Das würde einigen Aufwand erfordern, und Sie müßten Text verwenden, anstatt binäre Werte für Zahlen. Aber auf diese Weise könnte man einfach Readline- verwenden, um jede Variable zu lesen. Ihre Pakete würden wie folgt aussehen

[action ID]
[item 1 (as text)]
...
[item n (as text)]

-

Schließlich einfach Objekte serialisiert und Leiten sie den Draht nach unten ist ein guter Weg, dies zu tun, mit der geringsten Menge an Code zu schreiben. Denken Sie daran, dass Sie nicht wollen, vorzeitig optimieren, und das Netzwerkverkehr umfasst auch. Wenn sich herausstellt, müssen Sie später ein wenig mehr Leistung Squeeze-out auf Sie einen effizienteren Mechanismus zurück und herauszufinden, gehen kann.

Und Besuche Googles Protokollpuffer , die angeblich sind ein extreemly schneller Weg zur Serialisierung von Daten in einem plattformunabhängige Art und Weise, die Art wie ein binäres XML, aber ohne verschachtelte Elemente. Es gibt auch JSON , die eine weitere Plattform neutral Kodierung ist. Mit Protokollpuffern oder JSON würde bedeuten, Sie nicht zu befürchten habe, wie gesagt, um die Nachrichten zu codieren.

Möchten Sie den Server mehr Clients geschrieben in verschiedenen Sprachen zu unterstützen? Wenn nicht, ist es wahrscheinlich nicht notwendig, die Struktur zu spezifizieren genau; stattdessen unabhängig Einrichtung für Daten, die Ihre Sprache Angebote Serialisierung, einfach das Fehlerpotenzial zu reduzieren.

Wenn Sie die Struktur tun müssen tragbar sein, die oben sieht nicht gut aus, wenn Sie Sachen wie endianness und Textcodierung als auch in diesem Fall angeben sollen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top