# Einzelne Bits per Socket versenden



## Tho82 (1. Okt 2008)

Hallo,

ich habe eine Verbindung mit sehr wenig Bandbreite. Ich würde gerne per Socket/ServerSocket Daten übertragen. Da ich allerdings recht viele Informationen übertragen muss, will ich an jedem Bit, welches übertragen werden soll, sparen. Ich will z.B. folgendes übertragen:

100;2;XYZ;333.33333

Die Zahl 100 kann ich ja beispielsweise mit einem Byte Darstellen (0,0,1,0,0,1,1,0).
Die Zahl 2 ebenso mit einem Byte (0,1,0,0,0,0,0,0).
XYZ wird mit "XYZ".getBytes() in Bytes umgewandelt. DAnn habe ich hier 3 Bytes.
333.33333 ist ein Doublewert. Dieser hat in Java meines Wissens nach eine Größe von 64 Bits.
*
Hier meine Fragen: *

Wie wandel ich diesen Doublewert in Bytes um, damit ich den auch per Bytestream versenden kann? Gibts dafür eine Methode oder muss ich den Doublewert in einen String umwandeln und den String dann wiederum mit der Methode getBytes() in Byte umwandeln, was jedoch die Byte-Größe wieder vergrößern wurde (9*8 Bytes = 72 Bits anstatt 64 wie beim Doublewert)?


Gibt es auch die Möglichkeit, Bitweise über Sockel Daten zu versenden? D.H. wenn ich z.B. einen Wertebereich habe von 0-100 dann reichen mir ja 7 Bit um diese Zahl darzustellen?!? Andersrum gefragt: Wenn ich eine Zahl wie 10000 darstellen muss in Bits, wie wird das gemacht, denn 1 Byte kann ja nur Zahlen bis max 255 darstellen? 

Vielen Dank für eure Hilfe.


----------



## foobar (1. Okt 2008)

Festkommawerte überträgt man am besten mit der write-Methode: http://java.sun.com/j2se/1.4.2/docs/api/java/io/OutputStream.html#write(int)



> Gibt es auch die Möglichkeit, Bitweise über Sockel Daten zu versenden?


Nein, Integer ist schon die kleinste Einheit. D.h. es wird auf jeden Fall immer ein Byte übertragen.


----------



## Tho82 (1. Okt 2008)

Vielen Dank für deine Antwort.



			
				foobar hat gesagt.:
			
		

> Festkommawerte überträgt man am besten mit der write-Methode: http://java.sun.com/j2se/1.4.2/docs/api/java/io/OutputStream.html#write(int)



Mit der Methode kann ich doch nur int-Werte übertragen und keinen Double Wert? Oder soll ich jeweils den Wert vor Komma übertragen und danach den Wert nach Komma? Wenn du das so meinst ist das aber keine schöne Lösung. Also wenn ich 22.22222 übertragen will dann einmal 22 und einmal 22222 jeweils als integer.



> Nein, Integer ist schon die kleinste Einheit. D.h. es wird auf jeden Fall immer ein Byte übertragen.



Okay.. aber es ist möglich eine Zahl mit einem Byte darzustellen, also bei 2^8 wäre das eine Zahl bis max. 255?


----------



## tuxedo (1. Okt 2008)

>> aber es ist möglich eine Zahl mit einem Byte darzustellen, also bei 2^8 wäre das eine Zahl bis max. 255?

??? Das ist immer möglich. Ob jetzt -128..127 (oder wars -127..128?! Kann mir das einfach nicht merken) daraus interpretiert wird, oder 0..255 ist vollkommen dir überlassen. Ein byte hat nunmal 256 mögliche zustände. 

>> ich habe eine Verbindung mit sehr wenig Bandbreite. Ich würde gerne per Socket/ServerSocket Daten übertragen. Da ich allerdings recht viele Informationen übertragen muss, will ich an jedem Bit, welches übertragen werden soll, sparen.

Da stellt sich mir die Frage: Wie gering ist die Bandbreite? In der heutigen Zeit nennt man schon 115.200 Baud "gering". Aber da macht es wenig Sinn einzelne Bits zu sparen wenn man Megabyteweise Daten schaufeln will. Die ersparnis dürfte da zu gering sein als dass sich der Aufwand bezahlt macht. 

Oder hast du noch weniger Bandbreite? Was für ein Transfervolumen willst du denn über welche Bandbreite schicken?!

- Alex


----------



## Tho82 (1. Okt 2008)

tuxedo hat gesagt.:
			
		

> >> aber es ist möglich eine Zahl mit einem Byte darzustellen, also bei 2^8 wäre das eine Zahl bis max. 255?
> 
> ??? Das ist immer möglich. Ob jetzt -128..127 (oder wars -127..128?! Kann mir das einfach nicht merken) daraus interpretiert wird, oder 0..255 ist vollkommen dir überlassen. Ein byte hat nunmal 256 mögliche zustände.
> 
> ...



Danke für deine Antwort!

Also die Bandbreite ist 2,4kb/s, wird über ein digitales Funknetzwerk übertragen. Das Problem ist, dass die Daten an mehrere Clients übertragen werden müssen und von Zeit zu Zeit immer wieder (rund alle 30 Sekunden). Es sind informationen über Objekte, die auf dem Client dann auf einer Landkarte angezeigt werden sollen, sowas wie aktuelle position, anzuzueigendes bild (code), richtung der Bewegung usw... Und wenn das 20 Objekte sind, sollte es eben keine 5 sekunden gehn, bis die infos versendet wurden.


----------



## tuxedo (1. Okt 2008)

Okay, 2,4kbit/s ist wirklich wenig. Und die vielen Clients hängen alle in diesem 2,4kbit/s Netz? Wenn ja, dann ist die Nutzbandbreite doch gleich nochmal weniger weil noch ein Protokoll läuft, oder?! Oder ist das ein "Radio-Prinzip" mit einem Sender und vielen Empfängern? Also nur eine Einweg-Kommunikation?

Du könntest die Daten auch komprimieren, das würde wohl am meisten Bandbreite sparen und ist einfacher zu erledigen wie einzelne Bits bei der Übertragung eines Double-Werts zu sparen. 

- Alex


----------



## Tho82 (1. Okt 2008)

tuxedo hat gesagt.:
			
		

> Okay, 2,4kbit/s ist wirklich wenig. Und die vielen Clients hängen alle in diesem 2,4kbit/s Netz? Wenn ja, dann ist die Nutzbandbreite doch gleich nochmal weniger weil noch ein Protokoll läuft, oder?! Oder ist das ein "Radio-Prinzip" mit einem Sender und vielen Empfängern? Also nur eine Einweg-Kommunikation?
> 
> Du könntest die Daten auch komprimieren, das würde wohl am meisten Bandbreite sparen und ist einfacher zu erledigen wie einzelne Bits bei der Übertragung eines Double-Werts zu sparen.
> 
> - Alex



Also das ist noch unklar, aber ich hab es so verstanden, dass jeder Client die 2,4 kb/s kriegt.. Die Kommunikation soll evtl über TCP/IP laufen.

Meine Idee ursprünglich war, entweder Objekte direkt zu versenden, oder einen String zu formatieren mit JSON, weil das Marschalling dann übernommen wird. Da beide Möglichkeiten einen riesen Overhead produzieren, bleibt wohl nix anderes Übrig wie einen möglichst kurzen String rüberzusenden, den ich dann mit einem Trennzeichen wie zB ; trenne, und das Marshalling dann selbst übernehme.

Wie könnte man die Daten denn komprimieren?


----------



## tuxedo (1. Okt 2008)

>> Da beide Möglichkeiten einen riesen Overhead produzieren, bleibt wohl nix anderes Übrig wie einen möglichst kurzen String rüberzusenden, den ich dann mit einem Trennzeichen wie zB ; trenne, und das Marshalling dann selbst übernehme.


Oder sich die ; auch noch sparen und einen DataOutputStream nehmen und dort "nach Protokoll" erst einen Int, dann einen String und dann einen Double Wert verschicken. Musst dann halt nur auf der anderen Seite in genau der Reihenfolge genau die Typen wieder einlesen.

>> Wie könnte man die Daten denn komprimieren?

Ähm, ZIP kennst du? Gut, denn da gibt es auch noch passende Streams dafür: http://www.dpunkt.de/java/Programmieren_mit_Java/Streams/16.html

Oder aber selbst etwas ausdenken was für dich passend ist und vielleicht auf einem der vielen Algorithmen basiert die man im Netz so findet (Huffman, LZW und was es halt sonst noch so gibt).

- Alex

P.S. Wenn auf dieser schmalen Verbindung wirklich TCP/IP gsprochen wird, würde ich da einen Gateway zu einem schnelleren Netz (WLAN?) einsetzen und die Daten dort verteilen. Weil bei solch einem schmalbandigen Netz TCP/IP Einsetzen reduziert die Nutzbandbreite auf ein Minimum. Und wenn der Server dann die Daten noch an 20 Clients schicken muss, und das wirklich einzeln an jeden, dann geht alles in die Knie. Also lieber langsam an einen senden, der schnell an alle verteilen kann.


----------



## Guest (1. Okt 2008)

tuxedo hat gesagt.:
			
		

> >> Da beide Möglichkeiten einen riesen Overhead produzieren, bleibt wohl nix anderes Übrig wie einen möglichst kurzen String rüberzusenden, den ich dann mit einem Trennzeichen wie zB ; trenne, und das Marshalling dann selbst übernehme.
> 
> 
> Oder sich die ; auch noch sparen und einen DataOutputStream nehmen und dort "nach Protokoll" erst einen Int, dann einen String und dann einen Double Wert verschicken. Musst dann halt nur auf der anderen Seite in genau der Reihenfolge genau die Typen wieder einlesen.
> ...



Holla, also hab das gerade mal versucht, machs mir die Daten um einiges kleiner. Schade dass es da keine Methode wie writeDouble(...) oder writeObject(...) gibt, womit man die Daten im eigentlichen Datentyp versenden kann. Denkst ich soll die daten dann einfach immer in einen String umwandeln (Z.B. aus dem Double 22.22 einen String "22.22" machen und dann die methode getBytes aufrufen) oder gibts da möglichkeiten, auch komprimierte Double-Werte oder Komprimierte komplette Objekte zu versenden?

Anscheinend soll es hier einen Communikationserver geben, der die Kommunikation über UDP und SMTP regelt. Ich denke dieser wird in irgendeiner Weise den Handshake zwischen den 2 kommunizierenden Geräten steuern und die Pakete wieder in die Richtige Reihenfolge bringen. Denkst du also dass TCP/IP soviel kaputtmacht an Bandbreite und der Comm-Server daher schneller ist als über TCP/IP? Kannst du das irgendwie in Zahlen belegen und/oder mir nen Link senden?


----------



## tuxedo (1. Okt 2008)

>> oder gibts da möglichkeiten, auch komprimierte Double-Werte oder Komprimierte komplette Objekte zu versenden? 

Schau mal in der Java APIDOC nach "DataOutputStream". Das ist das was du letztendlich suchst....

>> Denkst du also dass TCP/IP soviel kaputtmacht an Bandbreite 

Ja. Sagt dir PacketRadio was? Ich hab zu meinen CB-Funk-Zeiten so ein 1200Baud Modem gehabt. Das ging mit dem AX25 Protokoll (sehr sparsam) noch recht fix. Aber sobal ich TCP/IP drauf gesetzt habe war fast schon ein Ping aufwendig. 

>> Kannst du das irgendwie in Zahlen belegen und/oder mir nen Link senden?

Google doch einfach mal nach "TCP/IP Overhead". 

Wenn ich mich recht entsinne hab ich in meiner Diplomarbeit da auch etwas dazu erwähnt. Sind auf jeden Fall mehr wie 1-2 Hand voll Bytes die da für's Protokoll benutzt werden.

Ich lad mal was hoch und verlinke es hier.. Dann hast du ein paar Zahlen ...(ansatzweise).

--> http://www.java-forum.org/de/userfiles/user2459/Diplomarbeit.pdf (Quelle: Meine Diplomarbeit zum Thema "Analyse, Design und Implementierung eines sterntopologischen Audiokonferenzsystems für Kontrollräume". Habs in der Quali etwas runtergedreht damit ich hier's hochladen kann).


----------



## Guest (2. Okt 2008)

tuxedo hat gesagt.:
			
		

> Schau mal in der Java APIDOC nach "DataOutputStream". Das ist das was du letztendlich suchst....



Ja genau, ich suche nach nem DataOutputStream, aber einen, der auch die Daten zippt.



			
				tuxedo hat gesagt.:
			
		

> Ja. Sagt dir PacketRadio was? Ich hab zu meinen CB-Funk-Zeiten so ein 1200Baud Modem gehabt. Das ging mit dem AX25 Protokoll (sehr sparsam) noch recht fix. Aber sobal ich TCP/IP drauf gesetzt habe war fast schon ein Ping aufwendig.



Okay. Wurde das dann mit UDP realisiert oder mit was?



			
				tuxedo hat gesagt.:
			
		

> Wenn ich mich recht entsinne hab ich in meiner Diplomarbeit da auch etwas dazu erwähnt. Sind auf jeden Fall mehr wie 1-2 Hand voll Bytes die da für's Protokoll benutzt werden.
> 
> Ich lad mal was hoch und verlinke es hier.. Dann hast du ein paar Zahlen ...(ansatzweise).
> 
> --> http://www.java-forum.org/de/userfiles/user2459/Diplomarbeit.pdf (Quelle: Meine Diplomarbeit zum Thema "Analyse, Design und Implementierung eines sterntopologischen Audiokonferenzsystems für Kontrollräume". Habs in der Quali etwas runtergedreht damit ich hier's hochladen kann).



Vielen Dank


----------



## tuxedo (2. Okt 2008)

>> Ja genau, ich suche nach nem DataOutputStream, aber einen, der auch die Daten zippt.


?? Du kannst doch Streams hintereinander schalten. Das ist ja das Prinzip von Streams ...

>> Okay. Wurde das dann mit UDP realisiert oder mit was? 

Nein, das wurde dann gar nicht realisiert. Ein Funkgerät kennt eben kein UDP oder TCP. Das kennt nur: Kanal aufschalten und Ton XYZ senden oder Kanal aufschalten und nach Ton lauschen. Darauf aufgesetzt ist das AX.25 Protokoll. Und da lässt sich dann beliebiges draufsetzen, mit dem Verlust von diversen Bytes wg. dem Mapping auf AX.25.

Das "beste" wäre, wenn man bei dem optimalen (im Falle von PacketRadio eben Ax.25) Protokoll bleibt und nix extra draufsetzt. Aber das geht ja nicht immer. Und dann muss man eben damit leben oder sich eine größere Bandbreite zulegen.

>> Vielen Dank 

Keine Ursache. Musst nur zwischen Ethernet und deinen Funknetz differenzieren. Auch in deinem Funknetz wirst du keine volle 2,4kbit Nutzbandbreite haben. Da gibts auch wieder ein Transportprotokoll das einen gewissen Overhead produziert. Um das ganze also exakt auszurechnen, müsste man wissen was das für ein Funknetz ist und welche Art von Übertragung dort von Haus aus stattfindet (vielleicht sogar auch Ax.25? Wobei.. das ist glaub ziemlich alt und "ausser mode"...).

- Alex


----------



## Guest (2. Okt 2008)

tuxedo hat gesagt.:
			
		

> ?? Du kannst doch Streams hintereinander schalten. Das ist ja das Prinzip von Streams ...



Sorry, kenne mich in Netzwerkprogrammierung bisher noch gar nicht aus. D.h. mein Code sieht dann aus wie folgt:

```
Socket server = new Socket(ip,port);
DataOutputStream out = new DataOutputStream(new GZIPOutputStream(server.getOutputStream))
out.writeDouble(22.222);
```



			
				tuxedo hat gesagt.:
			
		

> Keine Ursache. Musst nur zwischen Ethernet und deinen Funknetz differenzieren. Auch in deinem Funknetz wirst du keine volle 2,4kbit Nutzbandbreite haben. Da gibts auch wieder ein Transportprotokoll das einen gewissen Overhead produziert. Um das ganze also exakt auszurechnen, müsste man wissen was das für ein Funknetz ist und welche Art von Übertragung dort von Haus aus stattfindet (vielleicht sogar auch Ax.25? Wobei.. das ist glaub ziemlich alt und "ausser mode"...).



Sagt dir vielleicht TETRA was? --> de.wikipedia.org/wiki/TETRA


----------



## tuxedo (2. Okt 2008)

Jupp, TETRA kenn ich (kam in meiner DA auch vor).
Mich wundert nur dass du nur 2,4kbit zur Verfügung hast. TETRA kann ja rund das 10 Fache ...

- Alex


----------



## Guest (2. Okt 2008)

tuxedo hat gesagt.:
			
		

> Jupp, TETRA kenn ich (kam in meiner DA auch vor).
> Mich wundert nur dass du nur 2,4kbit zur Verfügung hast. TETRA kann ja rund das 10 Fache ...
> 
> - Alex



Ja schon. Kannst du mir vielleicht das was du über TETRA geschrieben hast auch zukommen lassen? Wie genau funktioniert da die Funkübertragung? Welches Protokoll usw?


----------



## tuxedo (2. Okt 2008)

So genau hab ich's nicht analysiert. Ich habs nur ergänzend erwähnt. Ging ja um Audiokonferenzsysteme auf IP Basis, und nicht um BOS-Funk.

Google doch einfach mal nach "TETRA Protokoll". Da kommt recht viel brauchbares zu Tage. Unter anderem ein Artikel von "Funkschau". Leider ist da wenig beschrieben wie das Datenprotokoll funktioniert.

Es gibt aber ein IEEE oder RFC oder so Dokument wo TETRA bis ins Detail beschrieben ist. Google ist dein Freund ;-)

- Alex


----------



## Tho82 (2. Okt 2008)

tuxedo hat gesagt.:
			
		

> So genau hab ich's nicht analysiert. Ich habs nur ergänzend erwähnt. Ging ja um Audiokonferenzsysteme auf IP Basis, und nicht um BOS-Funk.
> 
> Google doch einfach mal nach "TETRA Protokoll". Da kommt recht viel brauchbares zu Tage. Unter anderem ein Artikel von "Funkschau". Leider ist da wenig beschrieben wie das Datenprotokoll funktioniert.
> 
> ...



Vielen Dank für deine Hilfe, werde ich machen.

Viele Grüße Tho


----------

