PHP supports php code for resumable download and multipart download.
'*/*', 'User-agent' => 'mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0 )', 'Accept-Encoding '=> 'gzip, deflate', 'host' => $ url_info ['host'], 'connection' => 'close ', 'Accept-color' => 'zh-cn',); // merge heade $ headers = array_merge ($ def_headers, $ headers ); // get content length $ content_length = self: get_content_size ($ url_info ['host'], $ url_info ['port'], $ url_info ['request'], $ Headers, $ timeout); // content length not exist if (! $ Content_length) {throw new Exception ('content-Length is Not exists');} // get Exists length $ exists_length = is_file ($ save_file )? Filesize ($ save_file): 0; // get tmp data file $ data_file = $ save_file. '. data'; // get tmp data $ exists_data = is_file ($ data_file )? Json_decode (file_get_contents ($ data_file), 1): array (); // check file is valid if ($ exists_length = $ content_length) {$ exists_data & @ unlink ($ data_file); return true;} // check file is expire if ($ exists_data ['length']! = $ Content_length | $ exists_length> $ content_length) {$ exists_data = array ('length' => $ content_length,);} // write exists data file_put_contents ($ data_file, json_encode ($ exists_data); try {$ download_status = self: download_content ($ url_info ['host'], $ url_info ['port'], $ url_info ['request'], $ save_file, $ content_length, $ exists_length, $ speed, $ headers, $ timeout); if ($ download_status) {@ un Link ($ data_file) ;}} catch (Exception $ e) {throw new Exception ($ e-> getMessage ();} return true ;} /*** parse url ** @ param $ url * @ return bool | mixed */static function parse_url ($ url) {$ url_info = parse_url ($ url); if (! $ Url_info ['host']) {return false;} $ url_info ['port'] = $ url_info ['port']? $ Url_info ['host']: 80; $ url_info ['request'] = $ url_info ['path']. ($ url_info ['query']? '? '. $ Url_info ['query']: ''); return $ url_info ;} /*** download content by chunk ** @ param $ host * @ param $ port * @ param $ url_path * @ param $ headers * @ param $ timeout */static function download_content ($ host, $ port, $ url_path, $ save_file, $ content_length, $ range_start, $ speed, & $ headers, $ timeout) {$ request = self: build_header ('GET ', $ url_path, $ headers, $ range_start); $ fsocket = @ fsockopen ($ h Ost, $ port, $ errno, $ errstr, $ timeout); stream_set_blocking ($ fsocket, TRUE); stream_set_timeout ($ fsocket, $ timeout); fwrite ($ fsocket, $ request); $ status = stream_get_meta_data ($ fsocket); if ($ status ['timed _ out']) {throw new Exception ('socket Connect timeout ');} $ is_header_end = 0; $ total_size = $ range_start; $ file_fp = fopen ($ save_file, 'A + '); while (! Feof ($ fsocket) {if (! $ Is_header_end) {$ line = @ fgets ($ fsocket); if (in_array ($ line, array ("\ n", "\ r \ n "))) {$ is_header_end = 1;} continue;} $ resp = fread ($ fsocket, $ speed); $ read_length = strlen ($ resp ); if ($ resp = false | $ content_length <$ total_size + $ read_length) {fclose ($ fsocket); fclose ($ file_fp ); throw new Exception ('socket I/O Error Or File Was Changed ');} $ total_size + = $ read_length; fputs ($ file_fp, $ Resp); // check file end if ($ content_length = $ total_size) {break;} sleep (1); // for test // break ;} fclose ($ fsocket); fclose ($ file_fp); return true ;} /*** get content length ** @ param $ host * @ param $ port * @ param $ url_path * @ param $ headers * @ param $ timeout * @ return int */static function get_content_size ($ host, $ port, $ url_path, & $ headers, $ timeout) {$ request = self: build_header ('hea D', $ url_path, $ headers); $ fsocket = @ fsockopen ($ host, $ port, $ errno, $ errstr, $ timeout); stream_set_blocking ($ fsocket, TRUE ); stream_set_timeout ($ fsocket, $ timeout); fwrite ($ fsocket, $ request); $ status = stream_get_meta_data ($ fsocket); $ length = 0; if ($ status ['timed _ out']) {return 0;} while (! Feof ($ fsocket) {$ line = @ fgets ($ fsocket); if (in_array ($ line, array ("\ n", "\ r \ n "))) {break;} $ line = strtolower ($ line); // get location if (substr ($ line, 0, 9) = 'Location :') {$ location = trim (substr ($ line, 9); $ url_info = self: parse_url ($ location); if (! $ Url_info ['host']) {return 0;} fclose ($ fsocket); return self: get_content_size ($ url_info ['host'], $ url_info ['port'], $ url_info ['request'], $ headers, $ timeout);} // get content length if (strpos ($ line, 'content-length :')! = False) {list (, $ length) = explode ('content-length: ', $ line); $ length = (int) trim ($ length );}} fclose ($ fsocket); return $ length ;} /*** build header for socket ** @ param $ action * @ param $ url_path * @ param $ headers * @ param int $ range_start * @ return string */static function build_header ($ action, $ url_path, & $ headers, $ range_start =-1) {$ out = $ action. "{$ url_path} HTTP/1.0 \ r \ n"; foreach ($ headers as $ hkey => $ hval) {$ out. = $ hkey. ':'. $ hval. "\ r \ n";} if ($ range_start>-1) {$ out. = "Accept-Ranges: bytes \ r \ n"; $ out. = "Range: bytes = {$ range_start}-\ r \ n";} $ out. = "\ r \ n"; return $ out ;}# use age/* try {if (downloader: get (' http://dzs.aqtxt.com/files/11/23636/201604230358308081.rar ', 'Test.rar') {// todo echo 'download succ';} catch (Exception $ e) {echo 'download failed';} */?>