PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ByteArrayOutputStream() und Konsorten


Capt'N Coax
2004-08-01, 20:38:59
Hoi Allemann,

mir müsste mal schnell einer helfen, bin wieder den ganzen Tach am progg0rn und seh' momentan wieder den Wald vor lauter Bäumen nicht.


byteStreamOut = new ByteArrayOutputStream();
bOutputStream = new BufferedOutputStream(byteStreamOut);
gzipOut = new GZIPOutputStream(bOutputStream);
outputStream = new ObjectOutputStream(gzipOut);
outputStream.writeObject(object);


Es geht hier eigentlich darum, dass ich mir das ByteArrayOutputStream sparen kann, da ich schon ein anderweitig generiertes byte-Array bekomme.

Dieses andere byte-Array möchte ich gerne komprimieren.
Allerdings fällt mir nicht ein wie ich das anstellen soll.
Oder muss ich das byte-Array TROTZDEM wieder wieder über den ByteArrayOutputStream einlesen? Was schmeisst der mir denn dann raus?

grml,
Coax

HellHorse
2004-08-01, 23:19:51
Was willst du überhaupt in den Stream schreiben? Objekte oder ein byte Array?

Falls es ein ByteArray ist:

public class CapnCoax {
public static void main(String[] args) throws Exception {
byte[] data = new byte[]{1, 3, 3, 7};
FileOutputStream fos = new FileOutputStream("1337.net");
GZIPOutputStream zippedOut = new GZIPOutputStream(fos);
zippedOut.write(data);
zippedOut.close();
fos.close();

FileInputStream fis = new FileInputStream("1337.net");
GZIPInputStream zippedIn = new GZIPInputStream(fis);
for (int c = zippedIn.read(); c > 0; c = zippedIn.read()) {
System.out.print(c);
}
}
}

Funktioniert bei mir (man möge mir die Namen vergeben).

ByteArrayOutputStream ist sehr wahrscheinlich nicht, was du willst

This class implements an output stream in which the data is written into a byte array. The buffer automatically grows as data is written to it. The data can be retrieved using toByteArray() and toString().

http://java.sun.com/j2se/1.4.2/docs/api/java/io/ByteArrayOutputStream.html

Capt'N Coax
2004-08-02, 19:44:21
public class CapnCoax {


;D

Also, hab' mich wohl wieder krumm ausgedrückt.
Ich will auf keinen Fall eine Datei schreiben. Ich habe ein beliebiges Objekt in Java (Keine Datei), welches ich per byteArrayOutputStream in ein ByteArray serialisiere (Der Schritt ist VOR meinem Beispielcode hier schon erledigt worden).

Jetzt kommt das Problem:
Ich muss die binäre Differenz zwischen zwei byte-Arrays ermitteln (per XOR), und diese dann packen. Die Differenz ist natürlich auch ein byte-Array.

Das Programm läuft also folgendermaßen ab:
2 Objekte gleichen Typs werden serialisiert und als byte-Array ausgegeben, dann wird die Differenz zwischen den beiden Arrays ermittelt, und diese wiederum soll gepackt als Objekt mal versendet werden (halt nicht in eine Datei geschrieben oder per TCP, ich muss daraus ein Objekt machen).

Das Problem ist ja hier nur das ich als Eingangsobjekt ein Byte-Array habe. Das könnte ich wieder als Objekt übergeben, packen und mir als byte-Array per byteArrayBLAstream ausgeben lassen. Aber das kommt mir strange vor...abgesehen davon das Serialisierung relativ teuer ist.

Ich bin verwirrt.
Irgendwie ist das auch merkwürdig was ich da geschrieben habe... ;)

HellHorse
2004-08-02, 20:45:29
Mal schauen, ob ich es verstanden habe: :)

public class CaptnCoax {
public static void main(String[] args) throws Exception {
try2();
}

private static void try2() throws IOException {
Object o1 = new SerializableObject();
Object o2 = new SerializableObject();
ByteArrayOutputStream baStream = new ByteArrayOutputStream();
ObjectOutputStream ooStream = new ObjectOutputStream(baStream);
ooStream.writeObject(o1);
ooStream.flush();

byte[] o1data = baStream.toByteArray();
ooStream.reset();
baStream.reset();

ooStream.writeObject(o2);
ooStream.flush();
byte[] o2data = baStream.toByteArray();
ooStream.close();
baStream.close();

if (o1data.length == o2data.length) {
System.out.println("sizes did match");
int size = o1data.length;
byte[] diff = new byte[size];
for (int i = 0; i < size; ++i) {
diff[i] = (byte) (o1data[i] ^ o2data[i]);
}

FileOutputStream fos = new FileOutputStream("Captn.Coax");
GZIPOutputStream zippedOut = new GZIPOutputStream(fos);
zippedOut.write(diff);
} else {
System.out.println("sizes didn't match");
System.out.println("size of first: "+o1data.length);
System.out.println("size of second: "+o2data.length);
}
}

private static class SerializableObject implements Serializable {

}
}

Das Problem, das ich dabei sehe ist, dass du darauf angewiesen bist, dass die beiden Objekte serialisiert gleich lang sind.
Bei einem spontanversuch waren bei mir das erste immer 49 und das zweite immer 45 bytes lang. :???:
Aber vielleicht ist auch das wiederverwenden der Streams nicht so eine tolle Idee oder falsch gemacht. :(

Capt'N Coax
2004-08-02, 21:40:19
Original geschrieben von HellHorse
Das Problem, das ich dabei sehe ist, dass du darauf angewiesen bist, dass die beiden Objekte serialisiert gleich lang sind.


Sind beide vom gleichen Objekttyp und verfügen nicht über variable Arrays, also müsste doch die Objektlänge serialisiert die gleiche sein?
Der Inhalt spielt IMO doch keine Rolle.
Int ist Int, egal was drinsteht...

Ich habe allerdings nicht mit reset gearbeitet.

Original geschrieben von HellHorse
Bei einem spontanversuch waren bei mir das erste immer 49 und das zweite immer 45 bytes lang. :???:
Aber vielleicht ist auch das wiederverwenden der Streams nicht so eine tolle Idee oder falsch gemacht. :(

hmm...Kann aufgrund extrem wilder tests leider nicht mal eben schnell schauen, aber bin mir zu 99% sicher dass ich gestern die gleiche Länge heraushatte.

Aber offensichtlich habe ich an anderer Stelle noch ein Problem:

Original geschrieben von HellHorse
FileOutputStream fos = new FileOutputStream("Captn.Coax");
GZIPOutputStream zippedOut = new GZIPOutputStream(fos);
zippedOut.write(diff);


sehe ich das richtig, dass du den FileStream nicht in eine Datei schreibst, sondern in das byte-Array leitest?
Das ist vielleicht der Punkt der bei mir für Verwirrung sorgt...Wird denn durch


FileOutputStream fos = new FileOutputStream("Captn.Coax");


nicht ein Plattenzugriff realisiert?
Ist "Captn.Coax" nicht ein Dateibezeichner?

WENN das so klappt, probiere ich das morgen direkt mal mit einer (wieder funktionierenden) Version von mir :)

HellHorse
2004-08-02, 23:02:46
Original geschrieben von Capt'N Coax
Sind beide vom gleichen Objekttyp und verfügen nicht über variable Arrays, also müsste doch die Objektlänge serialisiert die gleiche sein?
Der Inhalt spielt IMO doch keine Rolle.
Int ist Int, egal was drinsteht...

Stimmt schon, habs ohne probiert und es ging. Dabei hatte ich so Freude an meinem Einfall. :(
Original geschrieben von Capt'N Coax
sehe ich das richtig, dass du den FileStream nicht in eine Datei schreibst, sondern in das byte-Array leitest?

Nö ich schreibe das byte Array in einen GZIPOutputStream, der in einen FileOutputStream schreibt.
Es wird also gepackt und dann in ein File geschrieben.
Original geschrieben von Capt'N Coax
Wird denn durch

FileOutputStream fos = new FileOutputStream("Captn.Coax");

nicht ein Plattenzugriff realisiert?
Doch, irgendwohin muss ich es ja schreiben. Und zum testen geht's viel einfacher als eine TCP-Verbindung.
Original geschrieben von Capt'N Coax
Ist "Captn.Coax" nicht ein Dateibezeichner?

Doch nütrlich. Noch nie von "COAX File"s gehört? :)
Original geschrieben von Capt'N Coax
WENN das so klappt, probiere ich das morgen direkt mal mit einer (wieder funktionierenden) Version von mir :)

Ich habe mal folgendes probiert und es läuft (nicht hauen, ich weiss, dass es nicht schön ist):

public class CaptnCoax {
public static void main(String[] args) throws Exception {
try3();
}

private static void try3() throws Exception {
SerializableObject o1 = new SerializableObject(1);
SerializableObject o2 = new SerializableObject(2);
ByteArrayOutputStream baStream1 = new ByteArrayOutputStream();
ObjectOutputStream ooStream1 = new ObjectOutputStream(baStream1);
ooStream1.writeObject(o1);
ooStream1.flush();

byte[] o1data = baStream1.toByteArray();
ooStream1.close();
baStream1.close();


ByteArrayOutputStream baStream2 = new ByteArrayOutputStream();
ObjectOutputStream ooStream2 = new ObjectOutputStream(baStream2);
ooStream2.writeObject(o2);
ooStream2.flush();
byte[] o2data = baStream2.toByteArray();
ooStream2.close();
baStream2.close();

if (o1data.length == o2data.length) {
System.out.println("sizes did match");
int size = o1data.length;
byte[] diff = new byte[size];
for (int i = 0; i < size; ++i) {
diff[i] = (byte) (o1data[i] ^ o2data[i]);
}

FileOutputStream fos = new FileOutputStream("Captn.Coax");
GZIPOutputStream zippedOut = new GZIPOutputStream(fos);
zippedOut.write(diff);
zippedOut.flush();
zippedOut.close();
fos.flush();
fos.close();

FileInputStream fis = new FileInputStream("Captn.Coax");
GZIPInputStream zippedIn = new GZIPInputStream(fis);
byte[] read = new byte[size];
zippedIn.read(read);
zippedIn.close();
fis.close();
for (int i = 0; i < size; ++i) {
read[i] = (byte) (read[i] ^ o1data[i]);
}
ByteArrayInputStream bais = new ByteArrayInputStream(read);
ObjectInput ios = new ObjectInputStream(bais);
SerializableObject o2reconstructed = (SerializableObject) ios.readObject();
System.out.println("o2.i: "+o2.i);
System.out.println("o2reconstructed.i: "+o2reconstructed.i);

} else {
System.out.println("sizes didn't match");
System.out.println("size of first: "+o1data.length);
System.out.println("size of second: "+o2data.length);
}
}

private static class SerializableObject implements Serializable {
public int i;
public SerializableObject(int i) {
this.i = i;
}
}
}

Was da passiert:

o1 serialisieren in ein byte array
o2 serialisieren in ein byte array
beide byte arrays xor'en
das Resultat gepackt in ein File schreiben
das Resultat wieder von dem File lesen und entpacken
das Resultat mit dem byte array von o1 xor'en
daraus ein Objekt erstellen => sieht aus wie o2

Capt'N Coax
2004-08-03, 19:01:58
Original geschrieben von HellHorse
Stimmt schon, habs ohne probiert und es ging. Dabei hatte ich so Freude an meinem Einfall. :(

;(

Original geschrieben von HellHorse
Doch, irgendwohin muss ich es ja schreiben. Und zum testen geht's viel einfacher als eine TCP-Verbindung.

Ja, nur das ist ja das was ich meine:
Es gibt keinen Stream-Typ, der den Stream in ein Objekt schreibt :)
Bzw. gibt es schon:
Den ByteArrayOutputStream halt.
Aber der Sinn des obigen Codes ist ja folgender:
In dem ich zwei Objekte voneinander abziehe bekomme ich ja eine Differenz. Ich gehe davon aus das sich von Frame zu Frame nur wenig innerhalb des Objektes ändert. Deswegen brauch ich eigentlich nur diese kleine Änderung upzudaten (in meinem Falle versenden, per UDP).

Der Vorteil an der Differenz:
Sie lässt sich wahrscheinlich gut packen.
Da ich jedoch kein TCP benutze, kann ich die Differenz (also das Byte Array) nicht in einen Stream packen, da ich später einmal DatagramPackets brauche (die ja ein byte-Array aufnehmen).
Du siehst: Wenn ich die Differenz so in ihrer ungepackten Form versende, habe ich größenmässig nichts gewonnen. Nur was mache ich jetzt mit meinem Byte-Array? Als Objekt definieren und wieder einem ByteArrayOutputStream übergeben, packen lassen, per UDP versenden, entpacken lassen (dann habe ich ja ein ByteArray)?

Während ich diese geistige Vergewaltigung schreibe, erkenne ich langsam dass meine Problemstellung sich nicht wirklich schön lösen lässt.

Original geschrieben von HellHorse
Doch nütrlich. Noch nie von "COAX File"s gehört? :)

*Hust* DOCH NA KLAR! SICHER! ;D Wer nicht?

Original geschrieben von HellHorse
Ich habe mal folgendes probiert und es läuft (nicht hauen, ich weiss, dass es nicht schön ist):

Ich finds schön :)

So, bin ma Fitnessstudio.
Hoffentlich kann ich das gleich noch programmieren :)

Capt'N Coax
2004-08-14, 14:44:13
Na jutt, hat ja wieder ewig gedauert bis ich an den Code kam. Böse Ausbildung.

Also, hab' mal drübergeschaut und auch mal was rumgestestet, ist alles wunderbar :).

Allerdings löst das mein Problem nur zum Teil:

Die Kernaussage ist folgende:
Wie bekomme ich ein komprimiertes byteArray?

Ich kann natürlich ohne Stress byte-Arrays aus Objekten machen, und davon das Delta ermitteln.
Jetzt habe ich aber nur die Möglichkeit, dieses (ungepackte) DeltaArray in einen (zip)Stream zu donnern. Und genau das hab ich nicht vor. Ich brauche keinen Stream mehr, sondern an dieser Stelle ein OBJEKT, welches mein byte-array komprimiert beeinhaltet.

Der Stream wäre zwar gepackt, aber ich kann damit nichts anfangen.

Einen Stream muss ich ja wieder irgendwo auffangen, was wunderbar wäre wenn ich über TCP laufe oder in eine Datei schreiben will. Aber beides kommt nicht in Frage da ich ein Laufzeitobjekt benötige (wegen UDP).

Meiner (vielleicht krummen) Denkweise nach sollte das ganze dann so aussehen:

(done bezeichnet Schritte die ich jetzt schon erledigen kann)

**************************

Serialisiere beliebige Objekte (statisch) / done
Leite Datenstrom in ein byte-Array / done
komprimiere das byte-Array in ein noch zu entwickelndes Objekt / not done
Serialisiere das zu entwickelnde Objekt / done
Schreibe es in ein byte-Array / done
Packe ein UDP Packet (kann nur byte-Array) / done
Senden / done

**************************

Was mich hierbei stört ist hoffentlich offensichtlich (hoffensichtlich):
Das zweifache Serialisieren von im Grunde genommen einem Objekt.
Ich brauche ein byte-Array, das komprimiert sein muss, keinen Strom. Ströme brauche ich nur um im Endeffekt aus einem Objekt einmal ein zu komprimierendes Array zu erstellen.

Und hier hänge ich jetzt fest.
So wie es aussieht muss ich wohl doch eine eigene Klasse schreiben, die mir mein Array "schrumpft". Warum das Sinn macht, kann ich euch an folgender Ausgabe zeigen:


************* UNGEPACKT ******************************************************************
Groesse des ungepackten Objektes 1: 73
Groesse des ungepackten Objektes 2: 73
Groesse des delta Objektes: 73
Objekt1:
-84 -19 0 5 115 114 0 10 116 101 115 116 111 98 106 101 107 116 -59 2 120 58 45 32 119 37 2 0 4 74 0 2 108 49 74 0 2 108 50 73 0 1 120 73 0 1 121 120 112 0 0 0 0 0 0 0 -22 0 0 0 0 0 0 1 89 0 0 0 2 0 0 0 4
Objekt2:
-84 -19 0 5 115 114 0 10 116 101 115 116 111 98 106 101 107 116 -59 2 120 58 45 32 119 37 2 0 4 74 0 2 108 49 74 0 2 108 50 73 0 1 120 73 0 1 121 120 112 0 0 0 0 0 0 1 68 0 0 0 0 0 0 1 -68 0 0 0 2 0 0 0 3
Delta:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 -82 0 0 0 0 0 0 0 -27 0 0 0 0 0 0 0 7



Es sollte offensichtlich sein, dass sich das Delta ENORM komprimieren lässt.
Und Huffman würde sich da wohl anbieten.

Also, wenn es da doch eine Möglichkeit gibt, oder einer schon einen Algo auf Lager hat der mir etwas Zeit spart, bitte nicht damit hinterm Berg halten ;)

cya,
Coax

Capt'N Coax
2004-08-14, 15:26:28
Inflater / Deflater perhaps?
Erfahrungen?

sonst gibt das zip Paket glaube ich nicht mehr viel her für meinen Zweck.

HellHorse
2004-08-14, 21:49:04
Langsam (glaube ich zumindest), sehe ich was du meinst ;)
Du willst die "Differenz" komprimieren und als byte[] haben, oder?

Mal angenommen die gepostete Differenz ist repräsentativ. Dann brauchen wir uns nur die Länge, und den Index und Wert von allen Elementen ungleich 0 zu merken und in ein int-Array zu packen (wegen den Indizes).
Es geht allerdings noch besser, wenn wir uns auf Arrays der mit maximaler Länge 0xFFFFFF beschränken, können wir den Wert und Index in einem int speichern.

public class DiffCompressor {
private static final int BORDER = 0xFFFFFF;

public static int[] compress(byte[] data) {
if (data.length > BORDER) {
throw new IllegalArgumentException("lenght of array to big, maximum allowed length: "+BORDER);
}
List<Integer> buffer = new LinkedList<Integer>();
buffer.add(data.length);

for (int i = 0; i < data.length; ++i) {
if (data[i] != 0) {
int encoded = encode(i, data[i]);
buffer.add(encoded);
}
}

int[] compressed = new int[buffer.size()];
for (int i = 0; i < compressed.length; ++i) {
compressed[i] = buffer.get(i);
}
return compressed;
}

public static byte[] decompress(int[] compressed) {
int size = compressed[0];
byte[] decompressed = new byte[size];
for (int i = 1; i < compressed.length; ++i) {
int encoded = compressed[i];
int index = decodeInt(encoded);
byte value = decodeByte(encoded);
decompressed[index] = value;
}

return decompressed;
}

public static int encode(int i, byte b) {
int shfited = ((int) b) << 24;
return i | shfited;
}

public static int decodeInt(int i) {
return i & BORDER;
}

public static byte decodeByte(int i) {
return (byte) (i >> 24);
}
}

Du willst wissen, ob der Scheiss auch läuft?

public class CompressorTest extends TestCase {
private byte[] data = new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -82, 0, 0, 0 , 0, 0, 0, 0, -27, 0, 0, 0, 0, 0, 0 , 0 , 7};

public CompressorTest(String name) {
super(name);
}

public void testBasic() {
int[] compressed = DiffCompressor.compress(data);
System.out.println("original size: "+data.length+", compressed size: "+compressed.length);
byte[] decompressed = DiffCompressor.decompress(compressed);
assertEquals(data.length, decompressed.length);
for (int i = 0; i < data.length; ++i) {
assertEquals(data[i], decompressed[i]);
}
}

public void testByte() {
int i = 1000;
byte b = 100;
int encoded = DiffCompressor.encode(i, b);
assertEquals(b, DiffCompressor.decodeByte(encoded));

b = -100;
encoded = DiffCompressor.encode(i, b);
assertEquals(b, DiffCompressor.decodeByte(encoded));
}

public void testInt() {
int i = 1000;
byte b = 100;
int encoded = DiffCompressor.encode(i, b);
assertEquals(i, DiffCompressor.decodeInt(encoded));

b = -100;
encoded = DiffCompressor.encode(i, b);
assertEquals(i, DiffCompressor.decodeInt(encoded));
}

public static void assertEquals(byte[] expected, byte[] actual) {
assertEquals(expected.length, actual.length);
for (int i = 0; i < actual.length; ++i) {
assertEquals(expected[i], actual[i]);
}
}

public void testStream() throws Exception {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
GZIPOutputStream gos = new GZIPOutputStream(bos);
gos.write(data);
gos.finish();
gos.flush();

byte[] compressed = bos.toByteArray();
System.out.println("original size: "+data.length+", stream gzip compressed size: "+compressed.length);

ByteArrayInputStream bis = new ByteArrayInputStream(compressed);
GZIPInputStream gis = new GZIPInputStream(bis);
List<Byte> buffer = new LinkedList<Byte>();
int next = gis.read();
while (next != -1) {
buffer.add((byte) next);
next = gis.read();
}

assertEquals(data.length, buffer.size());
for (int i = 0; i < data.length; ++i) {
assertEquals(data[i], (byte) buffer.get(i));
}
}
}

So komme ich ein deinem Beispiel von 73 byte auf 5 int's, also 20 bytes. Die Indices machen uns hier einen Strich durch die Rechnung. Allerdings nur, falls die byte's auch als byte's gesendet werden, und nicht als int's.

De/Inflater wäre eine andere Möglichkeit, allerdings bekam ich das Ding auf Anhieb allerdings nicht zum läufen.

public void testInDeflate() throws Exception {
Deflater deflater = new Deflater();
deflater.setInput(data);
deflater.finish();
byte[] compressed = new byte[(int) deflater.getTotalOut()];
deflater.deflate(compressed);
deflater.end();

System.out.println("original size: "+data.length+", in/deflate gzip compressed size: "+compressed.length);

Inflater inflater = new Inflater();
inflater.setInput(compressed);
byte[] decompressed = new byte[inflater.getTotalOut()];
inflater.inflate(decompressed);
inflater.end();
assertEquals(data, decompressed);
}


Ob das weniger Platz brauch ist eine andere Frage, wenn ich eine GZIPOutputStream und einen ByteArrayOutputStream verwende komme ich auf 31 bytes.

Kleine Anmerkung: Ja, ich weiss, dass meine Art Puffer (LinkedList und autoboxing) extrem ineffizient ist. Wer nicht selber etwas implementieren will, kann z.B. eine List_i verwenden:
http://www.kataba.com/dynamics/

HellHorse
2004-08-15, 10:32:29
Update:
Wenn du weisst, dass die Arrays nicht länger als 255 sind, kannst du auch ein ByteArray als output nehmen. An den Anfang schreibst du die Länge und dann abwechslungsweise Index und Wert der Elemente ungleich null. So kommst du von 73 auf 9 bytes.
Du musst allerdings aus den Indices ein "unsigned byte" machen, indem du 128 abziehst und später wieder addierst.
Das bringt aber wie schon gesagt nur was, wenn die bytes als bytes und nicht als ints versendet werden.

Capt'N Coax
2004-08-23, 19:29:29
Gut, ich gehe mal davon aus, dass sich der Großteil der Objekte relativ gut mit dem "Null"- Verfahren packen lassen wird.

Der Vorteil ist natürlich die saueinfache Implementation, obwohl es da ein Problem geben wird:

Die Arraygröße wird, denke ich, über 255 liegen.
Was aber auch kein Problem ist, da sich dieses lösen lässt, indem ich an Position 0 des komprimierten Arrays die Anzahl der nicht-Null Stellen schreibe, danach alternierend Position/Wert wie gehabt. Der Nachteil der Methode ist ein definitives byte pro Array, egal ob komplett mit Null belegt oder nicht, da ich ja auch ein komplett genulltes Array als solches erkennen muss.

Das große Problem was ich jetzt habe ist eigentlich nur noch folgendes:
Ich benötige später DEFINITIV mehrere OBJEKTE pro UDP-Paket.

Soll heissen:
Falls ein Paket verloren geht, sollte das nächste Paket dieses ausgleichen können. So muss also das Differenz Objekt in seinen letzten 3 (oder 2, egal) Versionen mitgeschickt werden, um fehlerhafte Übertragungen ohne zusätzlichen Sendeaufwand kompensieren zu können. Ebenfalls muss über eine einfache CRC Überprüfung nachgedacht werden.

In erster Linie gilts jetzt aber eine Möglichkeit zu finden, wie ich mehrere Objekte (jedes aus mehreren Byte-Arrays bestehend) innerhalb des (Gesamt)Byte Arrays unterscheiden kann...