您的位置:首页 > 理论基础 > 计算机网络

ASIHTTPRequest-实现断点续传-1

2015-07-10 15:07 561 查看
ASIHTTPRequest可以实现断点续传。网上有一些介绍类似使用:

[request setAllowResumeForFileDownloads:YES];

方法的。但是它不是真正意义的断点续传。它只能让应用在下载过程中,暂停和继续。如果退出应用再进入是无效的。

不过,通过ASIHTTPRequest的异步请求以及delegate还是可以实现断点续传的。

本文还是以Grails编写断点续传服务器端为例。

异步请求的代码:

-(void) doSimpleGetBinary{

NSURL *url = [NSURL URLWithString:@"http://localhost:8080/BookProto/book/image"];

ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];

[request setRequestMethod:@"GET"];

//[request addRequestHeader:@"Range" value:@"bytes=3-"];

[request setDelegate:self];

[request startAsynchronous];

}

这里设置了Delegate, 要在头文件中实现相应的protocol:

@interface CFHttpDemoViewController : UIViewController<ASIProgressDelegate> {

本例中使用到了delegate的如下方法。

requestFinished:

- (void)requestFinished:(ASIHTTPRequest *)request{

NSLog(@"response status code: %i",[request responseStatusCode]);

NSLog(@"response content length: %@",[[request responseHeaders] objectForKey:@"Content-Length" ]);

NSLog(@"request finished.");

label.text=@"request finished.";

}

这个方法在异步请求结束后调用。

下面的方法,是当缓冲区接收到部分数据后调用,看起来是每间隔一定的毫秒,就调用一下,并传入缓冲区的NSData对象。

-(void)request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data{

NSLog(@"did receive data, data length: %i",[data length]);

//复制到字节数组中

Byte *byteData=(Byte *)malloc([data length]);

memcpy(byteData,[data bytes],[data length]);

for (int i=0; i<=10; i++) {

NSLog(@"%i: %i",i+1,byteData[i]);

}

free(byteData);

[request cancel];

label.text=@"canceled.";

}

运行代码,屏蔽:

[request addRequestHeader:@"Range" value:@"bytes=3-"];

和取消屏蔽,数据分别如下:

2011-07-12 14:17:13.497 CFHttpDemo[2647:207] did receive data, data length: 10172

2011-07-12 14:17:13.514 CFHttpDemo[2647:207] 1: 137

2011-07-12 14:17:13.515 CFHttpDemo[2647:207] 2: 80

2011-07-12 14:17:13.516 CFHttpDemo[2647:207] 3: 78

2011-07-12 14:17:13.516 CFHttpDemo[2647:207] 4: 71

2011-07-12 14:17:13.517 CFHttpDemo[2647:207] 5: 13

2011-07-12 14:17:13.518 CFHttpDemo[2647:207] 6: 10

2011-07-12 14:17:13.518 CFHttpDemo[2647:207] 7: 26

2011-07-12 14:17:13.519 CFHttpDemo[2647:207] 8: 10

2011-07-12 14:17:13.520 CFHttpDemo[2647:207] 9: 0

2011-07-12 14:17:13.520 CFHttpDemo[2647:207] 10: 0

2011-07-12 14:17:13.521 CFHttpDemo[2647:207] 11: 0

2011-07-12 14:17:13.522 CFHttpDemo[2647:207] response status code: 200

2011-07-12 14:17:13.523 CFHttpDemo[2647:207] response content length: 10172

2011-07-12 14:17:13.523 CFHttpDemo[2647:207] request finished.
2011-07-12 14:02:24.551 CFHttpDemo[2578:207] did receive data, data length: 10169

2011-07-12 14:02:24.553 CFHttpDemo[2578:207] byteData ok.

2011-07-12 14:02:24.554 CFHttpDemo[2578:207] 1: 71

2011-07-12 14:02:24.554 CFHttpDemo[2578:207] 2: 13

2011-07-12 14:02:24.555 CFHttpDemo[2578:207] 3: 10

2011-07-12 14:02:24.555 CFHttpDemo[2578:207] 4: 26

2011-07-12 14:02:24.556 CFHttpDemo[2578:207] 5: 10

2011-07-12 14:02:24.556 CFHttpDemo[2578:207] 6: 0

2011-07-12 14:02:24.557 CFHttpDemo[2578:207] 7: 0

2011-07-12 14:02:24.557 CFHttpDemo[2578:207] 8: 0

2011-07-12 14:02:24.558 CFHttpDemo[2578:207] 9: 13

2011-07-12 14:02:24.558 CFHttpDemo[2578:207] 10: 73

2011-07-12 14:02:24.560 CFHttpDemo[2578:207] 11: 72

2011-07-12 14:02:24.561 CFHttpDemo[2578:207] response status code: 206

2011-07-12 14:02:24.561 CFHttpDemo[2578:207] response content length: 10169

2011-07-12 14:02:24.562 CFHttpDemo[2578:207] request finished.

2.

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);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: