iOS 基于HTTP协议的断点续传

> 原理

其实断点续传的原理很简单,就是在 Http 的请求上和一般的下载有所不同而已。

打个比方,浏览器请求服务器上的一个文时,所发出的请求如下:

假设服务器域名为 wwww.sjtu.edu.cn,文件名为 down.zip。

GET /down.zip HTTP/1.1

Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-

excel, application/msword, application/vnd.ms-powerpoint, */*

Accept-Language: zh-cn

Accept-Encoding: gzip, deflate

User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)

Connection: Keep-Alive

服务器收到请求后,按要求寻找请求的文件,提取文件的信息,然后返回给浏览器,返回信息如下:

200

Content-Length=106786028

Accept-Ranges=bytes

Date=Mon, 30 Apr 2001 12:56:11 GMT

ETag=W/"02ca57e173c11:95b"

Content-Type=application/octet-stream

Server=Microsoft-IIS/5.0

Last-Modified=Mon, 30 Apr 2001 12:56:11 GMT

所谓断点续传,也就是要从文件已经下载的地方开始继续下载。所以在客户端浏览器传给 Web 服务器的时候要多加一条信息 -- 从哪里开始。

下面是用自己编的一个"浏览器"来传递请求信息给 Web 服务器,要求从 2000070 字节开始。

GET /down.zip HTTP/1.0

User-Agent: NetFox

RANGE: bytes=2000070-

Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2

仔细看一下就会发现多了一行 RANGE: bytes=2000070-

这一行的意思就是告诉服务器 down.zip 这个文件从 2000070 字节开始传,前面的字节不用传了。

服务器收到这个请求以后,返回的信息如下:

206

Content-Length=106786028

Content-Range=bytes 2000070-106786027/106786028

Date=Mon, 30 Apr 2001 12:55:20 GMT

ETag=W/"02ca57e173c11:95b"

Content-Type=application/octet-stream

Server=Microsoft-IIS/5.0

Last-Modified=Mon, 30 Apr 2001 12:55:20 GMT

和前面服务器返回的信息比较一下,就会发现增加了一行:

Content-Range=bytes 2000070-106786027/106786028

返回的代码也改为 206 了,而不再是 200 了。

NSUrlConnection实现断点续传的关键是自定义http request的头部的range域属性。

Range头域

Range头域可以请求实体的一个或者多个子范围。例如,

表示头500个字节:bytes=0-499

表示第二个500字节:bytes=500-999

表示最后500个字节:bytes=-500

表示500字节以后的范围:bytes=500-

第一个和最后一个字节:bytes=0-0,-1

同时指定几个范围:bytes=500-600,601-999

但是服务器可以忽略此请求头,如果无条件GET包含Range请求头,响应会以状态码206(PartialContent)返回而不是以200(OK)。

在ios中使用NSMutableURLRequest来定义头部域


NSURL *url1=[NSURL URLWithString:@"下载地址";

NSMutableURLRequest* request1=[NSMutableURLRequest requestWithURL:url1];

[request1 setValue:@"bytes=20000-" forHTTPHeaderField:@"Range"];

[request1 setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];

NSData *returnData1 = [NSURLConnection sendSynchronousRequest:request1 returningResponse:nil error:nil];

[self writeToFile:returnData1 fileName:@"SOMEPATH"];

-(void)writeToFile:(NSData *)data fileName:(NSString *) fileName

{

NSString *filePath=[NSString stringWithFormat:@"%@",fileName];

if([[NSFileManager defaultManager] fileExistsAtPath:filePath] == NO){

NSLog(@"file not exist,create it...");

[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];

}else {

NSLog(@"file exist!!!");

}

FILE *file = fopen([fileName UTF8String], [@"ab+" UTF8String]);

if(file != NULL){

fseek(file, 0, SEEK_END);

}

int readSize = [data length];

fwrite((const void *)[data bytes], readSize, 1, file);

fclose(file);

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、概念(载录于:http://www.cnblogs.com/EricaMIN1987_IT/p/3837436...
    yuantao123434阅读 12,678评论 6 152
  • 工作流程 一次HTTP操作称为一个事务,其工作过程可分为四步: 1)首先客户机与服务器需要建立连接。只要单击某个超...
    保川阅读 10,052评论 2 14
  • Http协议详解 标签(空格分隔): Linux 声明:本片文章非原创,内容来源于博客园作者MIN飞翔的HTTP协...
    Sivin阅读 10,603评论 3 82
  • 蒲公英,风儿吹过,蒲公英洁白的种子随之飘散,轻轻地,缓缓地,飘向远方。一把把小伞的远去的理由,是重生,孕育新的生命...
    雪茉阅读 1,423评论 1 1
  • 果果: 你戴上妈妈给优优姐买的发夹,真像个女孩子,我们哈哈哈大笑起来...... 晚上我们检查数学卷时...
    热带毛毛虫阅读 1,144评论 0 3