So ein Blödsinn. Mit Strings ist es einfach und zudem noch „lesbar“. Aber es geht auch ohne weiteres ohne…
Man überlege nur mal was für einen Overhead mein SIMON hätte wenn ich alles mit Strings beschreiben müsste…
Was man mit Strings vielleicht so machen würde …
position=20,50 farbe=FFCC00
… könnte man mit nackten Bytes so machen (der Lesbarkeit wegen in Hex nieder geschrieben):
0x00 0x14 0x32 0x01 0xff 0xcc 0x00
Erklärung:
Einleitend gibt es immer ein byte das Beschreibt was folgt.
Angefangen wird mit 0x00, was in diesem Fall eine Position beschreibt. Hier wurde angenommen dass die x/y Position sich durch je ein Byte beschreiben lässt. Auch int (wären dann je 4 bytes) oder long (je 8 bytes) wären ohne weiteres möglich.
Nach dem „Tag“ 0x00 für "jetzt kommt eine x/y Position, kommen wie gesagt die x (0x14) und y (0x32) Position.
Da Positionsdaten in diesem Beispiel immer aus insgesamt 2 bytes bestehen, muss das nächste Byte das nächste „beschreibende“ Byte folgen: 0x01
Das steht in diesem Fall für "jetzt kommt eine RGB Farbe. FFCC00 wird hier dann zu 0xff, 0xcc und 0x00. Da RGB Farbangaben immer aus 3 bytes bestehen passt das so.
Wenn man etwas „dynamisch langes“ verschicken möchte, z.b. einen String, könnte man das so „codieren“
0x02 Als markierung für einen String
0x00
0x00
0x00
0xA0 Vier bytes als Integer. Hier 0x00, 0x00, 0x00 0xa0 = länge von 10
0x
0x
0x
0x
0x
0x
0x
0x
0x
0x ein 10 Zeichen langer String, byte für byte
Aber um auf das Eingangsbeispiel zurück zu kommen:
position=20,50 farbe=FFCC00 ----> 27 Bytes
0x00 0x14 0x32 0x01 0xff 0xcc 0x00 ------> 7 Bytes
Selbst wenn man die X/Y Position jetzt nicht mit Byte sondern mit Integer senden würde, wäre man noch deutlich unter 27 Bytes:
9 + fehlende 2x3 bytes = 13 statt 27 wie bei String… Zumal das String-Beispiel noch viel länger wird wenn man anfängt eine Integer-beschriebene POsition mal „auszureizen“. Denn da kann der längste Integerstring (-2147483647) 11 Zeichen lang werden. Mit Integer als byte ist und bleibt es bei 4 byte.
Das SIMON Protokoll sieht übrigens (vielleicht hilfts jemandem) so aus:
- Byte: Beschreibt die Art der Nachricht. Also „Platz“ für 256 verschiedene Nachrichtenarten im Protokoll
- bis 5. Byte: Vier Byte Integer-Wert. Damit verpasse ich jeder Nachricht eine Sequenz-Nummer um Request-Response zusammen finden zu lassen
- bis 9. Byte: Vier Byte Integer-Wert: Gibt die Länge der Nachfolgenden Nachricht an. Somit weiß ich beim lesen aus dem Stream wieviele Bytes ich noch lesen muss um die Nachricht für die weitere Verarbeitung in einen Worker-Thread stecken zu können, ohne die ganze Nachricht gleich parsen zu müssen.
- bis x. Byte: Die eigentliche Nachricht. Die Wahl der Verarbeitungsroutine wird am ersten Byte (Art der Nachricht) fest gemacht.
Damit habe ich einen „Protokolloverhead“ von lediglich 9 Bytes. Mit geschicktem Threading und Java NIO erreiche ich so in Extrem-Tests einen Nachrichtendurchsatz von fast 38.000 Nachrichten pro Sekunde auf Serverseite.