# Sockets und InputStream



## Malb (3. Mai 2007)

Ich empfange mittels Socket von einem Server einen Inputstream.
Das Problem hierbei ist:

- Ich kann den Inputstream nicht beenden, da der Socket ansonsten auch geschlossen wird (was die Abarbeitung der restlichen Netzwerkprotokols verhindern würde)
- Da ich den Stream aber nicht schließen kann tritt meine "while" Abbruchbedingung aber auch nie ein: while((len = in.read(buf)) > 0)

--> Wie kann ich jetzt aber feststellen ob der Datenstrom zuende ist?

Code:

```
InputStream in = null;
            
try
{
   in = socket.getInputStream()
}
catch ...
...
byte buf[] = new byte[puffer];


while((len = in.read(buf)) > 0) 
{   
...
```


----------



## Murray (3. Mai 2007)

Du könntest entweder vor den eigentlichen Daten die Länge (in einer definierten Anzahl von Bytes) übertragen, oder aber ein definiertes Ende-Byte (z.B. die 0) verwenden, welches in den zu übertragenden Daten natürlich nicht vorkommen darf. Im ersten Fall wird erst die Länge gelesen und dann eben soviele Bytes, wie die Längeninformation angibt; im zweiten Fall prüft man nach jeder Leseoperation, ob das Ende-Byte empfangen wurde.


----------



## Malb (4. Mai 2007)

OK. Beide Ideen habe ich ins Auge gefasst. Die mit der definierten Länge muss ich leider verwerfen, da ich eine Datei übertrage und erst am Ende weiss wie gross diese ist.

... Werde mich mal an einer -1 als Endezeichen versuchen


----------



## Guest (4. Mai 2007)

OK, die -1 funktioniert nicht. Was für einen Wert könnte ich da nehmen?


----------



## Murray (4. Mai 2007)

Wenn Du die Länge am Anfang noch nicht kennst, dann könntest Du die Ansätze auch mischen:
Du verwendest immer eine feste Blocklänge (z.B. 1024 Bytes). Der Sender schreibt die Datei 
dann blockweise, wobei die letzten Bytes eine Blocks keine Nutzdaten enthalten, sondern eine 
Kennung, die angibt, an welcher Stelle im Block die Nutzdaten aufhören (der letzte Block wird 
ja in der Regel nur zum Teil mit Nutzdaten gefüllt sein; der Rest wird dann z.B. mit Nullen aufgefüllt).
Wenn man jetzt einen Block empfangen hat, sieht man sich die Kennung am Ende an: steht hier eine 
Null, so enden die Nutzdaten nicht innerhalb des Blocks; es muss also mindestens ein weitere Block 
gelesen werden. Enden die Daten irgendwo innerhalb des Blocks, so muss nicht weitergelesen werden;
vom Block müssen genau soviele Bytes verwendet werden, wie die Kennung angibt.

Damit hat man zwar etwas Overhead beim Traffic erzeugt (weil man ja immer ganze Blöcke schreibt und so i.d.R. mehr Daten überträgt als notwendig), dafür dürfen die Daten dann aber auch sämtliche Byte-Werte enthalten, weil kein Wert als Ende-Kennung reserviert ist.


----------



## Malb (4. Mai 2007)

OK. Diese Lösung wäre denkbar. Habe mich aber schon auf deinen ersten Vorschlag eingeschossen und ihn 
implementiert. Und das schönste ist: er funktioniert schon. Habe aus breakbit den Wert -64 verwendet. Leider habe ich jetzt eben eine Datei gefunden, die diesen Wert enthält.

Gibt es nicht einfach einen Bitwert, den garantiert keine Datei enthält? Sowar wie NULL, -1, etc?


----------



## Murray (4. Mai 2007)

Allgemein gibt es einen solchen Wert nicht; Binärdateien können grundsätzlich alle möglichen Byte-Werte enthalten.


----------



## Malb (4. Mai 2007)

... Schade ... OK, ich habe ja jetzt einen Lösungsweg den ich gehen kann ...
Vielen Dank für deine Mühen


----------



## Tellerrand (5. Mai 2007)

Obwohl du eine Lösung schon hast noch ein Ansatz.



			
				Malb hat gesagt.:
			
		

> Gibt es nicht einfach einen Bitwert, den garantiert keine Datei enthält? Sowar wie NULL, -1, etc?



Gibt es nicht, ... aber:

Beim senden verdoppelst du im Datensegment alle -1 Bytes und ans Ende hängst du -1 0.

Beim empfangen prüfst du jedes Byte auf -1, wenn du eins findest  und das nachfolgende Byte auch -1 ist entfernst du eins. Ist das nachfolgende Byte nicht -1 demnach also 0 hast du das Ende erreicht.

Beispiel:

(-1 23 45 -1 21 -24 -1 -1) soll übertragen werden.
Übertragen wird also (-1 verdoppelt, eine -1 0 als Endbytes):
-1 -1 23 45 -1 -1 21 -24 -1 -1 -1 -1 -1 0
Nach der Filterung hätte man dann:
(-1 23 45 -1 21 -24 -1 -1)

0 und -1 sind hier rein willkürlich gewählt.


----------

