一直以来在项目中使用网络请求时,都是用AFN或苹果原生的NS请求类,最近突然有点好奇HTTP请求时,底层的实现过程是怎么样的,所以特意去学习了下。
网络架构
CFNetwork:依赖于Core Foundation框架的两个API,CFSocket和CFStream。
CFSocket:主要用于网络底层的通信,套接字是网络通信最基本的层级。一个套接字的作用类似与打电话的方式。它允许你连接到另一个套接字(无论本地或者通过网络)并将数据发送到该套接字。
CFStream:包括CFReadStream 和 CFWriteStream,分别用于对Socket的读取和写入。
CFHTTP:去发送和接收HTTP消息,使用CFHTTP API。
HTTP请求实现过程
1.使用CFHTTP的接口创建HTTP请求
2.使用CFStream的接口序列化和发送CFHTTP请求并接收响应
3.把响应转换为对应的格式(JSON)
//创建请求
CFStringRef url = CFSTR("https://app.*******.com/admin/index/start");
CFURLRef myURL = CFURLCreateWithString(kCFAllocatorDefault, url, NULL);
CFStringRef requestMethod = CFSTR("POST");
CFHTTPMessageRef myRequest =
CFHTTPMessageCreateRequest(kCFAllocatorDefault, requestMethod, myURL,
kCFHTTPVersion1_1);
// 设置body
NSData *dataToPost = [@"apptoken=-1" dataUsingEncoding:NSUTF8StringEncoding];
CFHTTPMessageSetBody(myRequest, (__bridge CFDataRef) dataToPost);
// 设置header
CFHTTPMessageSetHeaderFieldValue(myRequest, CFSTR("Content-Type"), CFSTR("application/x-www-form-urlencoded; charset=utf-8"));
//创建流并开启
CFReadStreamRef requestStream = CFReadStreamCreateForHTTPRequest(NULL, myRequest);
CFReadStreamOpen(requestStream);
//接收响应
NSMutableData *responseBytes = [NSMutableData data];
CFIndex numBytesRead = 0;
do {
UInt8 buf[1024];
numBytesRead = CFReadStreamRead(requestStream, buf, sizeof(buf));
if (numBytesRead > 0) {
[responseBytes appendBytes:buf length:numBytesRead];
}
} while (numBytesRead > 0);
CFHTTPMessageRef response = (CFHTTPMessageRef) CFReadStreamCopyProperty(requestStream, kCFStreamPropertyHTTPResponseHeader);
CFHTTPMessageSetBody(response, (__bridge CFDataRef)responseBytes);
CFReadStreamClose(requestStream);
CFRelease(requestStream);
CFAutorelease(response);
//转换为JSON
CFIndex statusCode;
statusCode = CFHTTPMessageGetResponseStatusCode(response);
CFDataRef responseDataRef = CFHTTPMessageCopyBody(response);
NSData *responseData = (__bridge NSData *)responseDataRef;
NSMutableDictionary *jsonInfo = [responseData JSONValue];
NSLog(@"responseBody: %@", jsonInfo);