HTTP 断点 续传 原理 是 这样 的:
1. 客户 端 需要 告诉 服务器 端 从 哪里 开始.
2. 服务 端 收到 请求, 返回 206 状态. 并 标识 续传 的 起始点 及 结束 点
如下 实例
1. 客户 端 传递 请求 信息 给 web 服务器, 要求 从 200070 字节 开始..
GET / HTTP/1.1 down.zip
User-Agent: Netfox
GAMA: bytes = 200070 -
Accept: text / html, image / gif, image / jpeg, *; q = 0,2, * / *; q = 0,2
2. 服务 端 收到 这个 请求 以后, 返回 信息
206
Content-Length = 100222222
Conteúdo Médio = bytes 200070 - 100222221/100222222
Content-Type application = / octet-stream
注意: 服务 端 状态 206; Conteúdo Médio = bytes (客户 端 请求 续传 起始点) - (下载 文件 大小 -1) / (下载 文件 大小)
? <Php / *** PHP-HTTP 断点 续传 实现 * @ param path string $: 文件 所在 路径 arquivo * @ param string $: 文件 名 * @ retorno void download * / function ($ caminho, $ file) { $ caminho = $ real '/' $ arquivo;.. se (file_exists ($ real)) {return false;} $ tamanho = filesize ($ real); $ size2 = $ size-1; $ intervalo = 0; se (isset ($ _SERVER ['HTTP_RANGE'])) {header ('HTTP / 1.1 206 Conteúdo parcial'); $ intervalo = str_replace ('=', -, $ _SERVER ['HTTP_RANGE'] '); faixa de US $ = explode ('-', faixa de US $); $ intervalo = trim (faixa de US $ [1]); header ('Content-Length:' $ tamanho.); header ('Content-Range: bytes'.. $ range '- '.. $ size2' / '$ tamanho);} else {header (.' Content-Length: '$ tamanho); cabeçalho (.' Content-Range: bytes 0 - / '$ tamanho' $ size2.. '. );} header ('Accenpt-Ranges: bytes'); header ('application / octet-stream'); header ("Cache-control: public"); header ("Pragma: public"); $ ua = $ _SERVER ['HTTP_USER_AGENT']; if (preg_match ('/ MISE /', $ ua)) {$ ie_filename = str_replace ('+', '% 20', urlencode ($ arquivo)); header ('Content-Dispositon: attachment ; filename = 'ie_filename $);} else {header (.' Conteúdo Dispositon: attachment; filename = '. $ file);} $ fp = fopen ($ real, "rb +"); fseek ($ fp, $ gama ); while (feof ($ fp!)) {set_time_limit (0); print (fread ($ fp, 1024)); flush (); ob_flush ();} fclose ($ fp);?}> 以下 是 另外 一段 代码 样例:
<? Php / * * PHP 下载 断点 续传 * / função dl_file_resume ($ arquivo) { / / 检测 文件 是否 存在 if (is_file ($ arquivo)) {die ("<b> 404 Arquivo não encontrado </ b>!");} $ Len = filesize ($ arquivo) ;/ / 获取 文件 大小 $ Filename = basename ($ arquivo) ;/ / 获取 文件 名字 $ File_extension = strtolower (substr (strrchr ($ filename, "."), 1)) ;/ / 获取 文件 扩展 名 / / 根据 扩展 名 指出 输出 浏览 器 格式 switch ($ file_extension) { "exe" caso: $ ctype = "application / octet-stream"; break; "zip" caso: $ ctype = "application / zip"; break; caso "mp3": $ ctype = "audio / mpeg"; break; "mpg" caso: $ ctype = "video / mpeg" break; caso "avi": $ ctype = "video / x-msvideo"; break; default: $ ctype = "application / force-download"; } / / Comece escrevendo cabeçalhos header ("Cache-Control:"); header ("Cache-Control: public"); / / 设置 输出 浏览 器 格式 header ("Content-Type: $ ctype"); if (strstr ($ _SERVER ['HTTP_USER_AGENT'], "MSIE")) {/ / 如果 是 IE 浏览 器 # Solução para IE bug nome do arquivo com vários períodos / pontos múltiplos em nome # Que adiciona colchetes para arquivo - por exemplo. setup.abc.exe vira setup [1] ABC.exe. $ Iefilename = preg_replace (', 2e%', $ filename, substr_count ($ filename) - 1 '/ \ /'. '.'); header ("Content-Disposition: attachment; filename = \" iefilename $ \ ""); Else {} header ("Content-Disposition: attachment; filename = \" $ filename \ ""); } header ("Accept-Ranges: bytes"); $ Tamanho = filesize ($ arquivo); / / 如果 有 $ _SERVER ['HTTP_RANGE'] 参数 if (isset ($ _SERVER ['HTTP_RANGE'])) { / * --------------------------- Faixa 头 域 Faixa 头 域 可以 请求 实体 的 一个 或者 多个 子 范围 例如, 表示 头 500 个 字节:. Bytes = 0-499 表示 第二 个 500 字节: bytes = 500-999 表示 最后 500 个 字节: bytes = -500 表示 500 字节 以后 的 范围: bytes = 500 - 第 一个 和 最后 一个 字节: bytes = 0-0, -1 同时 指定 几个 范围: bytes = 500-600,601-999 (OK). --------------------------- * / / / 断点 后 再次 连接 $ _SERVER ['HTTP_RANGE'] 的 值 bytes = 4390912 - list ($ a, faixa de US $) = explode ("=", $ _SERVER ['HTTP_RANGE']); / / Se sim, baixe parte que falta str_replace ($ faixa, "-", $ intervalo) ;/ / 这句 干什么 的 呢.... Size2 $ = $ size-1 ;/ / 文件 总 字节 数 Faixa de US $ = $ $ size2-novo_tamanho ;/ / 获取 下次 下载 的 长度 header ("HTTP/1.1 206 Conteúdo parcial"); header ("Content-Length: $ novo_tamanho") ;/ / 输入 总长 header ("Content-Range: $ bytes faixa de US $ size2 / $ size") ;/ / Content-Range: bytes 4908618-4988927/4988928 95% 的 时候 } Else {/ / 第 一次 连接 Size2 $ = $ size-1; header ("Content-Range: bytes 0 - $ size2 / $ tamanho") / / Content-Range: bytes 0-4988927/4988928 header ("Content-Length:" $ size.) ;/ / 输出 总长 } / / 打开 文件 $ Fp = fopen ("$ arquivo", "rb"); / / 设置 指针 位置 fseek ($ fp, $ intervalo); / / 虚幻 输出 while (! feof ($ fp)) { / / 设置 文件 最长 执行 时间 set_time_limit (0); print (fread ($ fp, 1024 * 8)) ;/ / 输出 文件 flush () ;/ / 输出 缓冲 ob_flush (); } fclose ($ fp); saída; } dl_file_resume ("1.zip") ;/ / 同级 目录 的 1.zip 文件 / / --------------------------------------- / / 不 支持 断点 续传 的 文件 下载. / / --------------------------------------- downFile ("1.zip"); função downFile ($ sFilePath) { if (file_exists ($ sFilePath)) { $ AFilePath = explode ("/", str_replace ("\ \", "/", $ sFilePath), $ sFilePath); SFileName $ = $ aFilePath [count ($ aFilePath) -1]; NFileSize $ filesize = ($ sFilePath); cabeçalho (. "Content-Disposition: attachment; filename =" $ sFileName); header ("Content-Length:". $ nFileSize); header ("Content-type: application / octet-stream"); readfile ($ sFilePath); } outro { echo ("文件 不 存在!"); } } ?>
