PHP主体直到套接字超时才返回


PHP Body not Returned Until Socket Timeout

[编辑:我正在尝试从PHP脚本向外部服务器发出HTTP请求]

我使用示例1从http://php.net/manual/en/function.fsockopen.php修改为:

<?php
$fp = fsockopen("m2.exosite.com", 80, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />'n";
} else {
    $out = "GET /api:v1/stack/alias?1 HTTP/1.1'r'n";
    $out .= "Host: m2.exosite.com'r'n";
    $out .= "X-Exosite-CIK: a32c85ba9dda45823be416246cf8b433baa068d7'r'n";
    $out .= "Accept: application/x-www-form-urlencoded; charset=utf-8'r'n'r'n";
    fwrite($fp, $out);
    while (!feof($fp)) {
        echo fgets($fp, 128);
    }
    fclose($fp);
}
?>

当我运行这个命令时,我在终端看到:

HTTP/1.1 200 OK
Date: Wed, 07 May 2014 13:51:40 GMT
Content-Length: 4
Connection: keep-alive
Server: nginx
<60 second pause>
1=37

然而,当我在wireshark中观察它时,我看到一个包含正文1=37的HTTP数据包被发送,同时我在我的终端中看到报头。但是,当服务器关闭套接字时,我只能在终端中看到主体(只是tcp [FIN, ACK],没有发送数据)。我认为这意味着响应的主体卡在PHP的某个地方。我需要做些什么才能让尸体被读出吗?

fgets的最后一次调用在等待换行符、读取128个字符或默认超时到期时阻塞。返回前面的行是因为它们以'n结尾。根据fgets()的文档:

读取长度为- 1字节时结束,或换行符(其中包含在返回值中),或EOF(以先出现的为准)。如果没有指定长度,它将继续从流中读取,直到它到达行尾

根据你想做的事情,你可能:

  • 发送头Connection: close,以便服务器关闭连接,这将使最后一个fgets调用返回。

  • 使用较小的超时值调用stream_set_timeout,使客户端提前停止等待。