2010-09-15 50 views
2

我必須編寫一個PHP腳本,作爲另一個HTTP服務器的客戶端。此服務器忽略HTTP連接:關閉標頭,並保持TCP連接處於打開狀態,除非它被客戶端關閉。這是我的困境。我(客戶端)必須決定HTTP請求/響應何時完成,然後關閉連接。簡單地使用:檢測HTTP數據包的結尾

$ data = file_get_contents($ url);

..將無法正常工作,因爲file_get_contents僅在連接超時(默認30秒)到達時纔會返回。

所以我必須寫我自己讀 - 像這樣的(僞代碼)循環:

$sock = fsockopen(...); 
$data = ''; 
while($line = fgets($sock)) { 
    $data .= $line; 
    if(http_package_recieved()) { 
     break; 
    } 
} 

不幸的是,在響應沒有Content-Length頭。我的問題是,如何在功能

http_package_recieved()

...應該像。

電賀 托爾斯滕

+1

這個問題今天被下調了 - 發佈後的5年。 downvoter可以解釋背後的原因嗎? – hek2mgl 2015-06-10 12:32:30

回答

2

如果它沒有關閉連接它不告訴你總的響應時間,你無法知道是否所有的數據都已收到。

您可以指定數據包之間的最大時間間隔,但這不可靠。

+1

如果使用HTTP分塊傳輸編碼,則可以使用它。 – Bruno 2010-09-15 13:49:32

+0

@布魯諾的確如此。如果情況如此(OP沒有具體說明)還有待觀察。 – Artefacto 2010-09-15 13:50:43

+0

@布魯諾:這是一個很大*如果*。但是,除非服務器指定了這個或Content-length並且不關閉連接,否則確實沒有辦法告訴(不應該發生,但顯然可以)。 – Piskvor 2010-09-15 13:59:07

0

feof($sock)將確定

1

當實體結束或者通過引導:

如果您得到此標頭,您可能需要處理此分塊傳輸編碼。有這樣的圖書館。

+0

傳輸編碼:分塊,我*有*。我會讀這個。謝謝。 – hek2mgl 2010-09-15 14:06:32

+0

我強烈建議使用庫來做到這一點,除非你有充分的理由不這樣做。 libcurl可通過PHP獲得(如@Rushyo所說)。 – Bruno 2010-09-15 14:09:30

3

您可以檢查$ line是否爲空以查看服務器是否未發送任何內容。您還可以使用stream_set_timeout()在套接字上設置一個較小的讀取超時時間,然後在循環中檢查stream_get_meta_data()以查看是否已達到該數量以便突破。