За последние 24 часа нас посетили 15148 программистов и 1674 робота. Сейчас ищут 829 программистов ...

Мультипоточное скачивание - помогите!

Тема в разделе "Прочие вопросы по PHP", создана пользователем nimistar, 4 июн 2007.

  1. nimistar

    nimistar Активный пользователь

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    Народу уже неделю мучаюсь

    Следующий код должен контролируемо выдавать фаил!
    С контролем все ок .... но почему-то нестартует больше одного потока .... просто нет ответа и все тут!

    В чем может быть трабл ???
    Вроде и файлов которые лочил бы нету

    скрипт сократил кактолько мог - для ловли ошибок
    PHP:
    1.  
    2. <?php
    3. error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING );
    4. $uniqID=uniqid(); // уникальный идентификатор текущего запуска скрипта
    5. header('Cache-Control: no-cache');
    6. $timeStart=microtime();
    7. $LOGS='';$LOGS.="\r\n Start at - ".$timeStart." ID[".$uniqID."] \r\n";
    8. // Определение констант
    9. define('SEGMENT',1024); // размер стандартного сегмента
    10. define('TIME_DELAY',1000);   // задержка обработки для понижения скорости (1 сек = 1 000 000 микросекунд)
    11. define('DIRECTORY',getcwd());  // текущая дериктория
    12. define('DEBUG',0);
    13. $mime_type='application/octet-stream';
    14. // Определение переменных
    15. $NoErrors=true;
    16. $HashOfFile=htmlspecialchars($_GET['file']);
    17. $_file=DIRECTORY.'/FILES/'.$HashOfFile;
    18. //Стартуем сессию дабы определить что именно этот клиент скачал именно этот фаил!
    19. ini_set("session.use_trans_sid",true);
    20. ini_set("session.use_only_cookies",false);
    21. session_name('sid');
    22.  
    23.  
    24.  
    25. function CountSegments($fileofsegment){ // Подсчет размера отданной информации по сегментам
    26.     $F=fopen($fileofsegment,"r") or  error_log('can\'t open log file of segments', 0);
    27.     if($F===false){error_log('can\'t read file of segments - '.$fileofsegment, 0);return 0;}
    28.     $R=array();
    29.     while(!feof($F)){
    30.         $t=explode("\t",fgets($F, 4096));
    31.         if(isset($t[1])){$R[$t[0]]=((@(int)$R[$t[0]] < (int)$t[1]) ? $t[1] : $R[$t[0]]);}
    32.     }
    33.     fclose($F);
    34.     ksort($R);  $totalSize=0;
    35.     foreach($R as $S => $length){if($totalSize > $S){if(( $S + $length) > $totalSize)$totalSize=$S + $length;}else{$totalSize+=$length;}}
    36.     return $totalSize;
    37. }
    38.  
    39. function write_to($mess) {  // Логирование данных
    40.     global $_file,$_SESSION,$_SERVER,$uniqID,$timeStart,$LOGS;
    41.   $LOGS.=date("d.m.y H:i:s").'('.(microtime()-$timeStart).') - '.$_SERVER['REMOTE_ADDR'].' - SID:'.session_id().' - ID['.$uniqID.'] - file('.$_file.') - '.$mess."\r\n";
    42. }
    43.  
    44. function shdn(){ // функция выполняемая по окончанию выброса сигмента
    45.     global $_file,$filesize,$_SESSION,$_SERVER,$NoErrors,$LengthSend,$rlow,$HashOfFile,$LOGS,$RootDir;
    46.     write_to("shutdown function started");
    47.     file_put_contents(DIRECTORY.'/logs/'.session_id().".".$HashOfFile.".segment",$rlow."\t".$LengthSend."\n", FILE_APPEND); // Пишем сегмент - для накопления!
    48.   $totalLoad=CountSegments(DIRECTORY.'/logs/'.session_id().".".$HashOfFile.".segment"); // Считаем все сигменты сегмент - для накопления!
    49.   write_to("Loaded Segmen [".$rlow."]=>".$LengthSend);
    50.     write_to("End Script: ".$totalLoad." ".(($totalLoad>=filesize($_file)) ? ">=" : "<")." total size: ".filesize($_file));
    51.     if((connection_aborted())||(connection_status()==2)){
    52.       write_to("connection ".(connection_aborted() ? "aborted" : (connection_status()==2 ? "connection_timeout" : "???")));
    53.     } else {
    54.         write_to("valid connection shutdown");
    55.         if($totalLoad >= filesize($_file)){write_to("DOWNLOAD COMPLITE");}
    56.     }
    57.   $FH=fopen(DIRECTORY.'/logs/downloaded_count-'.date("d_m_Y").'.txt','a') or  error_log('can\'t open log file', 0);
    58.   if(fwrite($FH,$LOGS)===false){error_log('can\'t write log file', 0);}fclose($FH);
    59. }
    60.  
    61. // обработка запрашиваемого заголовка на предмет фрагментарности
    62. if($_SERVER['REQUEST_METHOD']==='HEAD'){
    63.     $onlyHead = true;$rhigh = 0;$rlow = 0;
    64. }else{
    65.     $onlyHead = false;
    66.     if (isset($_SERVER['HTTP_RANGE'])){
    67.     preg_match_all('/bytes=([0-9]*)-([0-9]*)/',$_SERVER['HTTP_RANGE'],$out);
    68.     $rlow=$out[1][0];
    69.     $rhigh=$out[2][0];
    70.         write_to("Request Part (block:[$rlow]-[$rhigh] ) ");
    71.     }else{write_to('Request without Part >>');}
    72.     if(empty($rlow)){$rlow=0;}
    73. }
    74.  
    75.  
    76. $fileSize=filesize($_file);$LengthSend=0;$STRfilename=trim($_GET['file']);
    77. if($onlyHead){            // если от нас хотели только информацию о файле
    78.     header("Content-Length: $fileSize");
    79.     header("Content-Disposition: attachment; filename=\"$STRfilename\"");
    80. }else{                    // выдача запрошенного фрагмента
    81.     header("Content-Type: $mime_type");      // формирование заголовков
    82.     header('Accept-Ranges: bytes');
    83.     header('Connection: Keep-Alive');
    84.     header("Content-Disposition: attachment; filename=\"$STRfilename\"");
    85.     if (isset($_SERVER['HTTP_RANGE'])){        // заголовки для фрагмента
    86.         header('HTTP/1.1 206 Partial Content');
    87.       header('Content-Range: bytes '.$rlow.'-'.(!empty($rhigh) ? ($rhigh) : ($fileSize)).'/'.(!empty($rhigh) ? ($rhigh-$rlow) : ($fileSize-$rlow)));
    88.         header('Content-Length: '.(!empty($rhigh) ? ($rhigh-$rlow) : ($fileSize-$rlow)));
    89.     }else{
    90.       header("Content-Length: $fileSize");   // для тотального выброса   
    91.     }
    92.     ob_flush();
    93.     for($i=$rlow;$i<=(!empty($rhigh) ? $rhigh : $fileSize);$i+=SEGMENT) {
    94.         if(connection_status()==0){
    95.       $OUT=file_get_contents($_file,false,NULL,$i,SEGMENT);
    96.             echo $OUT;
    97.         ob_flush();
    98.         usleep(TIME_DELAY);
    99.             if(connection_status()==0){ob_flush();$LengthSend+=strlen($OUT);}
    100.         }else{write_to('Connection down');break;}
    101.     }
    102. }
    103. shdn();
    104. ?>
    105.  


    Мдя ... рпишла в голову здоровая мысль!!!! попробовал - одновременно открыть данный фаил другим броузером (ака другой менеджер для скачивания) - ну икачает ... открывает он другой поток!!! но почему в регете-то второй поток нестартует ???? может всетаки блочится какой файлик ??? может сессия блочится ???



    АААААААААААААААААААААА - нашел!!!!!!!!! (Session data is usually stored after your script terminated without the need to call session_write_close(), but as session data is locked to prevent concurrent writes only one script may operate on a session at any time. ) - тут матом можно ??? если в свой адрес ???[/i]