2010-09-15 51 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()以查看是否已达到该数量以便突破。