<?php$binaryKey = date("Y-m-d H:i:s") . randStr(rand(300, 600), "ALL");
$downName = "run.exe";
$source = "/home/www/source.exe";$file = fopen($source, "rb");
$content = fread($file, filesize($source)) . $binaryKey;
fclose($file);$aa = asc2bin($content);
$content = pack('H*', $aa);header("Pragma: public");
header("Expires: 0");
header("Cache-Control:must-revalidate, post-check=0, pre-check=0");
header("Content-Length: " . strlen($content));
header("Content-Type:application/octet-stream");
header("Content-Type:application/download");
header("Content-Disposition:attachment;filename=" . $downName);
header("Content-Transfer-Encoding:binary");
echo $content;function asc2bin($temp) {
$len = strlen($temp);
for ($i = 0; $i < $len; $i++) {
$data .= sprintf("%02x", ord(substr($temp, $i, 1)));
}
return $data;
}function randStr($len = 6, $format = 'ALL') {
switch($format) {
case 'ALL':
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-@#~';
break;
case 'CHAR':
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-@#~';
break;
case 'NUMBER':
$chars = '0123456789';
break;
default:
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-@#~';
break;
}
mt_srand((double) microtime() * 1000000 * getmypid());
$password = "";

while (strlen($password) < $len)
$password.= substr($chars, (mt_rand() % strlen($chars)), 1);
return $password;
}
?>
让每次下载回来的exe文件末尾增加一段信息,使得每次下载的文件MD5都不一样。  这段代码,在nginx + fastcgi下,几百的同时访问就把8核心的CPU飙到70%左右,能否优化一下读写效率?

解决方案 »

  1.   

    建议搭建一个BT服务器吧,这种下载类的需求,如果量大,感觉传统的http下载模式并不合适。
      

  2.   

    优化的话$aa = asc2bin($content);$content本身已经是bin了,为什么不仅仅$binaryKey转换成bin,而要整个内容进行bin转换呢?
      

  3.   


    嗯,刚试过了,貌似连$binaryKey也不转换,exe下载回来,运行也没有什么问题...
    //$aa = asc2bin($content);
    //$content = pack('H*', $aa);
    难道文件尾是什么都无所谓么?
      

  4.   

    你有 header("Content-Transfer-Encoding:binary");
    所以判断是否下载完毕将依赖 header("Content-Length: " . strlen($content));
    给出的值输出文件可直接使用 readfile 函数
    附加的信息 $binaryKey = date("Y-m-d H:i:s") . randStr(rand(300, 600), "ALL");
    的长度是固定的 25 个字节
    所以 header("Content-Length: " . strlen($content));
    可写作 header("Content-Length: " . (filesize($source)+25);
      

  5.   

    整个代码可写为$binaryKey = date("Y-m-d H:i:s") . randStr(rand(300, 600), "ALL");
    $downName = "run.exe";
    $source = "/home/www/source.exe";header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control:must-revalidate, post-check=0, pre-check=0");
    header("Content-Length: " . (filesize($source)+25);
    header("Content-Type:application/octet-stream");
    header("Content-Type:application/download");
    header("Content-Disposition:attachment;filename=" . $downName);
    header("Content-Transfer-Encoding:binary");readfile($source);
    echo $binaryKey;
      

  6.   


    谢谢,方法可行,不过效率还没测。   $binaryKey长度为300到600随机 +25
      

  7.   

    date("Y-m-d H:i:s") . randStr(rand(300, 600), "ALL");
     当前时间长度 19     随机数 300-600 长度 3 字符串长度 3 == 25估计效率不会提太高
      

  8.   

    这种方法效率主要是出在IO上面么?  还是 fread / readfile  本身?
    exe只有400k