12 Stimmen

Lesen, was vom Socket verfügbar ist, ohne zu blockieren

Ich arbeite an einem Server, der die vom Client gesendeten Daten liest, aber die Größe ist weder bekannt, noch kann ich den Client so ändern, dass er die Größe sendet.

Ich möchte die Daten vom Client lesen, bis er blockiert und auf die Antwort des Servers wartet. Ich habe versucht, mit available() funktioniert es manchmal, aber manchmal gibt es einfach Null zurück, auch wenn einige Daten im Stream sind.

while((len = in.available()) != 0)
    in.read(b,0,len);

Gibt es eine Möglichkeit, dies in Java zu tun? Ich weiß, dass es asynchrone Methoden gibt, aber ich habe das noch nie ausprobiert, wenn also jemand ein kurzes Beispiel geben kann.

7voto

Grodriguez Punkte 21042

Verwendung von available() ist die einzige Möglichkeit, dies zu tun, ohne auf asynchrone Methoden zurückzugreifen.

Sie müssen sich nicht unbedingt auf den Wert verlassen, der von available() nur prüfen, ob "einige" Daten vorhanden sind, um sicherzustellen, dass read wird nicht blockiert. Sie müssen jedoch den Wert prüfen, der von read (die tatsächliche Anzahl der in das Array eingelesenen Bytes):

// Process all data currently available
while (in.available() != 0)
{
    int nb = in.read(b);
    // Process nb bytes
}

Beachten Sie, dass available Die Rückgabe von 0 bedeutet nicht, dass das Ende der Daten erreicht wurde - es bedeutet lediglich, dass keine Daten zum sofortigen Verbrauch verfügbar sind (Daten können in der nächsten Millisekunde verfügbar werden). Sie benötigen also einen anderen Mechanismus, damit der Server weiß, dass der Client keine weiteren Daten senden wird und stattdessen auf eine Antwort wartet.

4voto

asgs Punkte 3828

[InputStream JavaDocs](http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#available()) für die Methode available() eindeutig fest, dass

Beachten Sie, dass einige Implementierungen von InputStream zwar die Gesamtzahl der Bytes im Stream zurückgeben, viele jedoch nicht. Es ist niemals den Rückgabewert dieser Methode zu verwenden, um einen Puffer zuzuweisen zuzuweisen, der alle Daten in diesem Stream aufnehmen soll.

Sie sollten stattdessen die read() Methode, um Daten in einen Puffer fester Größe zu lesen, der z.B. 4096 Bytes umfasst.

2voto

vovahost Punkte 29502

Ich habe viele Lösungen ausprobiert, aber die einzige, die ich gefunden habe, die die Ausführung nicht blockiert, ist die:

BufferedReader inStream = new BufferedReader(new InputStreamReader(yourInputStream));
String line;
while(inStream.ready() && (line = inStream.readLine()) != null) {
    System.out.println(line);
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X