我添加了一個示例代碼,該做的工作對我來說。它使用CFReadStreamHasBytesAvailable()。檢查流的狀態非常重要,否則可能會導致無限循環。我的例子還包括超時處理。
NSMutableData* bodyData = [NSMutableData dataWithCapacity:kHTTPReadStreamBufferSize];
NSDate* startTimeStamp = [NSDate date];
while (TRUE) {
if (CFReadStreamHasBytesAvailable(httpReadStream)) {
startTimeStamp = [NSDate date];
UInt8* streambuffer = malloc(kHTTPReadStreamBufferSize);
int readBytes = CFReadStreamRead (httpReadStream,streambuffer,kHTTPReadStreamBufferSize);
NSLog(@"Read: %d",readBytes);
[bodyData appendBytes:streambuffer length:readBytes];
free(streambuffer);
}
if (CFReadStreamGetStatus(httpReadStream) == kCFStreamStatusError) {
*error = (NSError*)CFReadStreamCopyError (httpReadStream);
if ([*error code] == 61) {
NSLog(@"Error occured: %d",[*error code]);
// connection refused
[PlusError errorForDomainWithCode:kPlusHostUnreachable errorDescription:NSLocalizedString(@"kPlusHostUnreachable",@"")
underlyingError:nil url:nil toError:error];
}
*responseHeader = nil;
*bodyContent = nil;
break;
}
if (CFReadStreamGetStatus(httpReadStream) == kCFStreamStatusAtEnd) {
NSLog(@"Stream reached end!");
*responseHeader = (CFHTTPMessageRef)CFReadStreamCopyProperty(httpReadStream, kCFStreamPropertyHTTPResponseHeader);
*error = nil;
break;
}
// timeout management
NSTimeInterval timeInterval = [startTimeStamp timeIntervalSinceNow]*-1;
if (timeInterval >= kHTTPReadTimeOutTimeInSeconds) {
[PlusError errorForDomainWithCode:kPlusResourceLoadingError errorDescription:NSLocalizedString(@"kPlusResourceLoadingError",@"")
underlyingError:nil url:nil toError:error];
break;
}
}
爲了明確這一點:當我得到一個kCFStreamEventHasBytesAvailable通知爲文檔說,第一次調用CFReadStreamRead將是安全的。但是,我們不知道CFReadStreamRead返回的原因是否是因爲緩衝區是不夠大或流套接字沒有更多的數據。如果在第一次通知之前收到所有1200字節的數據,我們可能無法獲得其他數據的額外通知。所以我們應該再次調用CFReadStreamRead,並且不保證第二個調用不會被阻塞。這個假設是否正確? – Kay 2010-07-28 07:42:24