iOS 正确接收 HTTP chunked 数据的方法

iOS 上的 NSURLConnection 一般能处理绝大部分的 HTTP 请求场景, 不过, 对于一种情况, 它无法处理, 那便是接收 HTTP chunked data. NSURLConnectionDataDelegate 有一个方法, 可以在读取到部分响应时进行回调, 但是, 数据不是按 HTTP chunked data 来接收的, 它会将多个 chunk 合并到一起.

@protocol NSURLConnectionDataDelegate 
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
@end

没办法, 只能使用 cURL for iOS, 在iComet 的 iOS 例子里有介绍.

首先, 下载 cURL for iOS:http://seiryu.home.comcast.net/~seiryu/libcurl-ios.html

然后, 把里面的 libcurl.a 引入你的项目, 还要把它的头文件引入. 注意, cURL 依赖 libz.dylib.

完整代码:

#include "curl/curl.h"

@interface ViewController (){
    CURL *_curl;
}
@end

// this function is called in a separated thread,
// it gets called when receive msg from icomet server
size_t icomet_callback(char *ptr, size_t size, size_t nmemb, void *userdata){
    const size_t sizeInBytes = size*nmemb;
    NSData *data = [[NSData alloc] initWithBytes:ptr length:sizeInBytes];
    NSString* s = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    NSLog(@"%@", s);
    // beware of multi-thread issue
    return sizeInBytes;
}

@implementation ViewController

- (void)viewDidLoad {
    [self performSelectorInBackground:@selector(startStreaming) withObject:nil];
}

- (void)startStreaming{
	const char *url = "http://127.0.0.1:8100/stream?cname=a&seq=1";
    _curl = curl_easy_init();
    curl_easy_setopt(_curl, CURLOPT_URL, url);
    curl_easy_setopt(_curl, CURLOPT_NOSIGNAL, 1L); 
    curl_easy_setopt(_curl, CURLOPT_USERAGENT, curl_version());
    curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, icomet_callback);
    curl_easy_perform(_curl);
    curl_easy_cleanup(_curl);
}

Related posts:

  1. HTTP POST using PHP cURL
  2. HTTP 长连接技术 Comet
  3. 使用 jemalloc 编译过程出错的问题
  4. 小心 int 乘法溢出!
  5. Objective C urlencode urldecode

发表评论

Close Menu