2012-02-23 62 views
3

我正在致力於瀏覽器/代理服務的項目,我需要下載網頁。在將自定義HTTP請求發送到Web服務器後,我開始監聽服務器響應。如何知道HTTP服務器何時完成發送數據

當讀取響應時,我檢查Content-Length:-row的響應標題。如果我得到其中的一個,那麼很容易確定服務器何時完成發送數據,因爲我總是知道我收到了多少個字節的數據。

當服務器不包含Content-Length標頭並且還將連接保持打開狀態以便進一步請求時,就會出現問題。例如,谷歌服務器響應gzip-content,但不包括內容長度。我如何知道何時停止等待更多數據並關閉連接?

我已經考慮過在一段時間內沒有收到數據的時候使用超時值來關閉連接,但是這似乎是錯誤的做法。例如,Chrome可以像我一樣下載相同的頁面,並且似乎總是知道何時關閉連接。

回答

2

查看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 2012-02-23 12:34:22

1

我會試着建議你強制Connection: close標題,所以無論Content-length是否設置,您都確信服務器在輸出完成後關閉連接。性能將部分受此影響

+0

感謝您的回答。這是我已經嘗試過的,但許多服務器忽略了這一點,所以它不是傻瓜式的。另外,如果查看Chrome發送的請求,可以看到它始終使用連接:保持活動狀態,但仍然知道何時完成。因此,我認爲這是(即使它有時會起作用)解決問題的錯誤方法。 – Accatyyc 2012-02-23 12:27:03

+0

如果服務器忽略連接:關閉然後你有一個很大的麻煩,需要使用一個非常短的超時(如2秒)。 Connection:close要求服務器關閉連接。不關閉連接是違反協議。此外,我可能懷疑Chrome預計標籤確定「已完成」 – 2012-02-23 12:34:05

+0

我不這麼認爲,因爲在解壓縮之前閱讀壓縮文檔的HTML標籤是沒有意義的。看看bew的答案。 Chrome通過讀取塊大小來解決這個問題。 – Accatyyc 2012-02-23 12:42:29

0

有兩種情況,你可以期望: 1.插座靠近 2.插座超時

通常插座將被關閉,這也是有道理的申報插座時間到。

記住

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

返回字節[]的真實大小 - 已讀,直到插座接近或套接字超時(或大小參數達到)參數的大小。

問候。

相關問題