iOS 正确接收 HTTP chunked 数据的方法
jopen
9年前
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); }