# Input-/OutputStream Frage



## hexxenhammer (19. Mrz 2010)

Hallohallo Gemeinde,

bin sonst nicht so sehr in Foren unterwegs, aber ich bräuchte mal Hilfe bei einem Problem, das mir derzeit Kopfzerbrechen bereitet.
Und zwar handelt es sich um ein Chatprogramm auf Client/Server Basis, bei der Strings hin und her gesendet werden. Das funkioniert derzeit alles einwandfrei. Nun hab ich mir überlegt anstelle von Strings lieber Objekte zu schicken, da ich darin mehr Informationen transportieren kann (wie z.b. Schriftart/Farbe/etc...).

Der Client arbeitet wie folgt:

Er läuft in einer while Schleife und prüft ob es neue Nachrichten gibt.
Bisher war es so, dass ich dafür BufferedWriter bzw. BufferedReader benutzt habe.
Das hatte den Vorteil, dass ich immer abfragen konnte ob denn wirklich etwas im Bufferedreader drin steckt, 
mit Hilfe von BufferedReader.ready().

was so aussieht:


```
input = new BufferedReader(new InputStreamReader(server.getInputStream()));
if (input.ready() == true) 
{
   ...
   String txt = input.readLine();
   ...
}
```


Wenn ich nun ObjectInputStream benutze hab ich leider keine solche Funktion. was dann so aussieht:

```
input = new BufferedInputStream(server.getInputStream());
Message tmp_msg = (Message) input.readObject();
```

Mein Client bleibt dann also einfach hängen bei der 2. Zeile und reagiert aber dementsprechend nicht mehr auf was anderes (wie senden zb). Gibt es eine Möglichkeit für ObjectInputStream ähnlich der .ready()-Funktion bei BufferedReader?

Wenn ja, wäre es nett, wenn ihr mir das mitteilen könntet.
Wenn nicht, hab ihr eine Idee, wie man das Abfragen auf ankommende Nachrichten(Objekte) anders gestalten könnte?


----------



## Murray (19. Mrz 2010)

hexxenhammer hat gesagt.:


> Gibt es eine Möglichkeit für ObjectInputStream ähnlich der .ready()-Funktion bei BufferedReader?


Wie wäre es mit InputStreamavailable()? Damit hat man zwar keine Garantie, dass das Objekt bereits vollständig gelesen werden kann, aber das ist mit BufferedRead.ready ja ähnlich. In beiden Fällen bekommt man aber mit, dass der Server zumindest angefangen hat, Daten zu schreiben - insofern lohnt es sich, mit dem Lesen anzufangen.


----------



## Kr0e (19. Mrz 2010)

Hmm,  du musst mit Threads arbeiten. Socketprogrammierung ohne NIO funktioniert in Java nicht ohne Threads (Sofern du Sachen gleichzeitig bearbeiten willst).
Ich hab mal gehört die avaible() Methode muss nicht unbedingt auf jeder Plattform das richtige ausgeben. 

Davon abgesehen hast du bei Objekten ein anderes Problem. Wenn du readObject() aufrufst, dann wird solange gelesen, bis das Objekt da ist. Wenn du nun mit avaiable überprüfst wieviel Daten da sind, weißt du immernoch nicht, bei welche Größe du dann endlich readObject aufrufen darfst, ohne dass die Methode blockiert...

Mach nen Thread der die ganze Zeit empfängt und ggf. schläft. Mach nen Handler, der, falls ein Objekt da ist, aufgerufen wird, danach geh wieder auf recv. Dein Programm wird dann nciht stocken, da nur der Lesethread blockiert...

Gruß,
Chris


----------



## ice-breaker (19. Mrz 2010)

```
available()
```
 des InputStreams gibt immer 0 zurück, die Methode ist wahrscheinlich erst bei gebufferten Streams sinnvoll, die darüber ausgeben können, wieviele Bits im Buffer sind


----------



## Murray (19. Mrz 2010)

ice-breaker hat gesagt.:


> ```
> available()
> ```
> des InputStreams gibt immer 0 zurück, die Methode ist wahrscheinlich erst bei gebufferten Streams sinnvoll, die darüber ausgeben können, wieviele Bits im Buffer sind


Das ist korrekt; er verwendet hier ja auch einen BufferedInputStream, mit dem es klappen sollte. Insofern war der Link auf die Doku der Basisklasse sicher etwas verwirrend.


----------



## SlaterB (19. Mrz 2010)

wie soll der BufferedInputStream diese Information aus dem InputStream erhalten?
wenn man mal alte Daten im Puffer vom vorherigen Senden außer acht läßt, kann man doch auf diesen Weg nicht mitbekommen, 'dass der Server zumindest angefangen hat, Daten zu schreiben', oder?
man müsste erst ein read() ausführen, welches dann blockieren kann, falls der Server doch noch nichts gesendet hat

aber stimmt schon, was immer da vorher beim BufferedReader geklappt hat, müsste mit available() nun genauso funktionieren


----------



## Murray (19. Mrz 2010)

SlaterB hat gesagt.:


> wie soll der BufferedInputStream diese Information aus dem InputStream erhalten?
> wenn man mal alte Daten im Puffer vom vorherigen Senden außer acht läßt, kann man doch auf diesen Weg nicht mitbekommen, 'dass der Server zumindest angefangen hat, Daten zu schreiben', oder?
> man müsste erst ein read() ausführen, welches dann blockieren kann, falls der Server doch noch nichts gesendet hat


Stimmt, Asche auf mein Haupt, da hast du natürlich Recht - über available bekommt man bestenfalls mit, wenn bei vorhergehenden Read-Operationen bereits weitere Daten in den Buffer gepackt worden sind. Von selbst (also ohne eine ggfs. blockierende Read-Operation) wird sich der Buffer nicht füllen. Insofern ist es hier sinnlos, per available prüfen zu wollen, ob neue Daten vorliegen.


----------

