换另一种方式来读数据:
<?php
function httpPost($host,$url,$data,$p)
{
$conn = fsockopen($host,80,$errno, $errstr, 30);
if (!$conn)
{
echo "$errstr ($errno)<br />\n";
return;
}
$header = "POST ".$url." HTTP/1.1\r\n";
$header.= "Host : {$host}\r\n";
$header.= "Content-type: application/x-www-form-urlencoded\r\n";
$header.= "Content-Length:".strlen($data)."\r\n";
$header.= "Connection: Keep-Alive\r\n\r\n";
$header.= "{$data}\r\n\r\n";
fwrite($conn,$header);
//读内容
$resp='';
$start = microtime(true);
/*
* echo "开始读<br>";
while (!feof($conn)) {
echo "读之前:".(microtime(true)-$start)."<br>";
$resp .= fread($conn,64);
echo "读之后:".(microtime(true)-$start)."<br>";
}
*/
$len=-1;
//开始读头,读到空行时,表明头已读完
echo "开始读head<br>";
while( ($line=trim(fgets($conn))) != "" )
{
echo "head读之前:".(microtime(true)-$start)."<br>";
$header.=$line;
if(strstr($line,"Content-Length:"))
{
list($cl,$len)=explode(" ",$line);
}
echo "head读之后:".(microtime(true)-$start)."<br>";
}
echo "开始读body:".(microtime(true)-$start)."<br>";
$body=fread($conn,$len);
echo "内容:".$body."<br>";
echo "读完关闭前:".(microtime(true)-$start)."<br>";
fclose($conn);
echo "关闭:".(microtime(true)-$start)."<br>";
return $resp;
}
httpPost("127.0.0.1","/aa.php","test",true);
?>
结果:
开始读head
head读之前:0.00082898139953613
head读之后:0.00084185600280762
head读之前:0.00084590911865234
head读之后:0.00084781646728516
head读之前:0.00085091590881348
head读之后:0.00085282325744629
head读之前:0.00085592269897461
head读之后:0.00085783004760742
head读之前:0.00085997581481934
head读之后:0.00086688995361328
head读之前:0.0008699893951416
head读之后:0.00087189674377441
head读之前:0.00087499618530273
head读之后:0.00087690353393555
head读之前:0.00088000297546387
head读之后:0.00088191032409668
开始读body:0.00088381767272949
内容:hello
读完关闭前:0.00088787078857422
关闭:0.0009307861328125
整个过程速度很快。
纵观两个函数及耗时,我觉得是feof判断结束有bug。所以推荐读SOCK的做法是,先取到协议头里的Content-Length,然后再根据Content-Length指定的长度读内容。
欢迎讨论。