服务器返回的响应中包含了当前返回内容的长度。
iis返回一个content-length.根据这个长度来循环,每遇到一个\r\n就加1。遇不到则跳出。
这样文件指针就不会错误地被指向远处。或者没有达到结尾就结束。然而。如果服务器输出的内容的所有行并不都包含\r\n呢。我不知道怎么解决。请各位兄弟指点迷津。
iis返回一个content-length.根据这个长度来循环,每遇到一个\r\n就加1。遇不到则跳出。
这样文件指针就不会错误地被指向远处。或者没有达到结尾就结束。然而。如果服务器输出的内容的所有行并不都包含\r\n呢。我不知道怎么解决。请各位兄弟指点迷津。
当 fp 由 fopen() 打开 "http://...." 或是 "ftp://...." 等 URL 文件时,本函数无法作用。也适用与fsockopen吗?我不清楚哦,可能你要试一下。
{
$fp = fsockopen($website, 80, $errno, $errstr, 30);
if ($fp)
{
$out = "GET " . $url . " HTTP/1.1\r\n";
$out .= "Host: " . $website . "\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
$str = "";
while (!feof($fp))
{
stream_set_timeout($fp, 200);
$str .= fread($fp, 8192);
$info = stream_get_meta_data($fp);
if ($info['timed_out'])
{
$str = "";
break;
}
}
fclose($fp); // 去掉http头
preg_match("/\r\n\r\n(.+)/is", $str, $out);
$str = $out[1];
return $str;
}
}
{
$service_port = getservbyname('www', 'tcp');
$address = gethostbyname($website);
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$socket_result = socket_connect($socket, $address, $service_port)) $in = "GET " . $url . " HTTP/1.1\r\n";
$in .= "Host: " . $website . "\r\n";
$in .= "Connection: close\r\n\r\n";
socket_write($socket, $in, strlen($in));
$str = "";
do
{
if (false === ($out = socket_read($socket, 1024)))
{
$str = "";
break;
}
$str .= $out;
} while ($out != "");
socket_close($socket);
return $str;
}
必须保证在一次fsockopen的过程中进行数次请求。while !feof不行才来求助的。
我已经似乎解决了这个问题。测试本地的apache服务器没有问题,正在处理细节。
再做请求是没有任何问题的。在请求的头里将Connection设置为keep-alive即可。
-----------------
头大了。有部分服务器可以正确地得到数据了,比如google,csdn。然而winzheng.com的,baidu的都不行。
----------------------------------
我的解决思路是。用fgets得到响应的头部,从头部中取得当前返回的字节数a。
根据这个数字a/4096得到循环次数n,用fread请求n次,a%4096得到余数mb,用fread请求mb个字节。
最后用fread请求7个字节。这7个字节我认为是服务器返回的终结字符,是我反复测试得到的。
这样做的结果是google和我本地的服务器以及csdn都可以正确地得到数据。
bbs.winzheng.com和baidu的都不行。