2012-02-23 17 views
3

私はブラウザ/プロキシ指向プロジェクトでWebページをダウンロードする必要があります。カスタムHTTPリクエストをWebサーバーに送信した後、私はサーバー応答のリスニングを開始します。HTTPサーバーがデータ送信を完了したときを知る方法

レスポンスを読むとき、レスポンスヘッダーでContent-Length:-rowを調べます。そのうちの1つを取得した場合、受信したデータのバイト数がわかっているので、サーバーがいつデータを送信したかを判断するのは簡単です。

この問題は、サーバーにContent-Lengthヘッダーが含まれておらず、以降の要求に対して接続を開いたままにしている場合に発生します。たとえば、Googleサーバーはgzipped-contentで応答しますが、コンテンツの長さは含みません。どのデータを待つのを止めて接続を閉じるのかを知るにはどうすればよいですか?

しばらくの間データが受信されていないときにタイムアウト値を使用して接続を閉じることを検討しましたが、これは間違った方法です。たとえば、Chromeは私と同じページをダウンロードでき、いつ接続をいつ閉じるかを正確に知っているようです。

答えて

2

チャンクエンコードとContent-Rangeを検索するIETF RfC 2616をご覧ください。

HTTPはのように、未知の長さの内容を返すように設計されています。答えを

HTTP/1.1 200 OK 
Content-Type: text/plain 
Transfer-Encoding: chunked 

25 
This is the data in the first chunk 

1C 
and this is the second one 

3 
con 
8 
sequence 
0 

source Wikipedia

+0

これは圧縮データにも当てはまる場合、これを解決する正しい方法と思われます。 (Content-Lengthが不足している私の要求のうち、Transfer-Encoding:ヘッダーを見たことがあると思います)。ありがとう! – Accatyyc

1

Content-lengthが設定されているかどうかにかかわらず、出力が終了した後にサーバーが接続を閉じることが確実になるように、Connection: closeヘッダーを強制的に表示するようにします。 1.ソケットクローズ通常のソケットが閉じられます 2.ソケットのタイムアウト

、それはまた、ソケットを宣言しても意味が:パフォーマンスは、部分的に2例は、あなたが期待することができますがあります。この

+0

感謝を。これは私がすでに試したことですが、多くのサーバーがこれを無視してしまいます。また、Chromeが送信するリクエストを見ても、常に接続:キープアライブを使用していることがわかりますが、完了した時点はまだ分かります。したがって、私はこれが解決するための間違った方法であると考えています。 – Accatyyc

+0

サーバーが接続を無視する場合:閉じると大きな問題が発生し、非常に短いタイムアウト(2秒など)を使用する必要があります。 Connection:closeを実行すると、サーバーは接続を閉じる必要があります。接続を閉じることはプロトコル違反です。また、私は、クロムがタグが「完了しました」と判断すると予想している可能性があります。 –

+0

圧縮された文書のHTMLタグを解凍するまで読むのは意味がありません。 bewの答えを見てください。 Chromeはチャンクサイズを読み取って解決します。 – Accatyyc

0

によって影響を受けることになりますタイムアウト。ソケットクローズまたはソケットタイムアウトまで読み(またはサイズ引数が到達)された引数のサイズ -

int stream.read(byte[],size); 

を覚えて、バイト[]の本当のサイズを返します。

よろしくお願いいたします。

関連する問題