Android でこの問題に取り組んでいますが、Android 固有の問題ではありません。
org.apache.http.client.HttpClient を使用して、サイズ 1kb の URL にリクエストを送信すると、レスポンス全体が HttpResponse に含まれます。
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("http://10.16.83.67/1kb.log");
HttpResponse response = null;
BufferedReader rd = null;
response = client.execute(request);
次に、応答から HttpEntity を取得できます。
HttpEntity entity = response.getEntity();
rd = new BufferedReader(new InputStreamReader(entity.getContent()));
そして、BufferedReaderで...
while ((line = rd.readLine()) != null) {
// ... parse or whatever
}
WireShark を見ていると、上記のコードの各方向に 1 つの送信が見られます。ログ ファイルの要求で、ログ全体が応答で配信されます。
ただし、たとえば 1 MB のログ ファイルなど、より大きなものを要求すると、非常に異なるものが表示されます。 データはフレームにチャンクされ、rd.readLine()
ループ内のワイヤを介してストリーミングされます。
初期応答には最初の kb 程度が含まれているようです。しかし、readLine()
実行すると、サーバーに追加のリクエストが行われ、データがソケットにストリーミングされます。ネットワーク接続が中断されると、IO エラーが発生します。大規模なリクエストの場合entity.isStreaming()
は、 true
.
これは非同期呼び出しです (ネットワーク呼び出しは UI スレッドで行うことができないため、Android では必須です) が、この要求からのすべてのデータの受信が完了したことを確認するまで続行したくありません。残念ながら、しばらく待ってから続行し、最善の結果を期待することはできません。
私の質問はこれです: 私のHttpClient
、HttpGet
、HttpResponse
、またはHttpEntity
オブジェクトは、このリクエストからのデータの受信がいつ完了したかを知っていますか? または、ストリームがいつ閉じられるかを知るために BufferedReader に頼る必要がありますか?