HttpRequest 的 CFReadStream
CFReadStream For HttpRequest
我必须开发一个终端工具应用程序以每 20 秒创建一个守护进程 运行。
这个Deamon只做这一步
- 验证是否存在一个文件:在这个文件里面读一遍
- 从 USB 连接的设备读取所有 serial_numbers
- 创建 HTTP 请求并在查询字符串上发送此参数
前 2 steph 运行 完美,但在发送 HTTPRequest 后主线程退出应用程序,因为不等待响应。
这是我的 HTTPRequest 代码:(我必须使用 CoreFoundation Framework,因为 Foundation Framework 中的 NSConnection 不是 运行)
for (int i = 0; i < [_arrayOfSerial count]; i++) {
CFStringRef urlFirst = CFSTR("http://192.168.30.9:88/virtualBadge.aspx?token=");
CFStringRef token =(CFStringRef)_codicePWD;
CFStringRef urlSecond = CFSTR("&serial=");
CFStringRef serial = (CFStringRef) [_arrayOfSerial objectAtIndex:i];
NSLog(@"URL: %@%@%@%@", urlFirst,token,urlSecond,serial);
CFStringRef strs[4];
strs[0] = urlFirst;
strs[1] = token;
strs[2] = urlSecond;
strs[3] = serial;
CFArrayRef urlArray = CFArrayCreate(kCFAllocatorDefault, (void*)strs, 4, &kCFTypeArrayCallBacks);
CFStringRef urlCompleta = CFStringCreateByCombiningStrings(kCFAllocatorDefault, urlArray, CFSTR(""));
NSLog(@"Url: %@",urlCompleta);
CFURLRef myURL = CFURLCreateWithString(kCFAllocatorDefault, urlCompleta, NULL);
CFStringRef headerFieldName = CFSTR("host");
CFStringRef headerFieldValue = CFSTR("192.168.30.9");
CFStringRef requestMethod = CFSTR("GET");
CFHTTPMessageRef myRequest =CFHTTPMessageCreateRequest(kCFAllocatorDefault, requestMethod, myURL, kCFHTTPVersion1_1);
CFHTTPMessageSetHeaderFieldValue(myRequest, headerFieldName, headerFieldValue);
CFDataRef mySerializedRequest = CFHTTPMessageCopySerializedMessage(myRequest);
if(CFHTTPMessageIsRequest(myRequest)){
NSLog(@"Is a Request: OK");
if(CFHTTPMessageIsHeaderComplete(myRequest)){
NSLog(@"Header OK");
}
}
CFReadStreamRef myReadStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, myRequest);
CFOptionFlags events = kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered | kCFStreamEventCanAcceptBytes | kCFStreamEventNone | kCFStreamEventOpenCompleted;
CFStreamClientContext dataStreamContext = {
0,
self,
(void *(*)(void *info))CFRetain,
(void (*)(void *info))CFRelease,
(CFStringRef (*)(void *info))CFCopyDescription
};
if(CFReadStreamSetClient(myReadStream, events, EvenCallBack, &dataStreamContext)){
CFReadStreamScheduleWithRunLoop(myReadStream, CFRunLoopGetMain(), kCFRunLoopCommonModes);
}
if(CFReadStreamOpen(myReadStream)){
NSLog(@"Stream Open - ");
}
NSString *messReq = [[[NSString alloc] initWithData:(NSData*)mySerializedRequest encoding:NSASCIIStringEncoding] autorelease];
CFRelease(myRequest);
CFRelease(myURL);
CFRelease(urlArray);
CFRelease(urlCompleta);
CFRelease(myReadStream);
NSLog(@"Serialized Request: %@", messReq);
// NSLog(@"Request Send");
}
"EvenCallBack" 函数永远不会调用,因为主线程退出:
int main(int argc, const char * argv[])
{
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
Demone* demone = [[Demone alloc] init]; //This is the class that start all process
[demone startDemone]; //Function start process
[demone release];
}
NSLog(@"Exit");
return 0;
}
我的错误在哪里?
为什么应用从不等待响应?
你启动了恶魔,它可能会进入后台。在它完成之前你释放它。比它没了...
来自 documentation 我的意思是您需要设置一个客户端,然后等待来自流的响应。您的应用在启动恶魔后就退出了。
您可以在 main 中使用 while 循环并检查流是否完成。然后就可以退出了。只要你在 while 循环中给 runloop 计算时间,例如 [NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:3]];
。
我必须开发一个终端工具应用程序以每 20 秒创建一个守护进程 运行。
这个Deamon只做这一步
- 验证是否存在一个文件:在这个文件里面读一遍
- 从 USB 连接的设备读取所有 serial_numbers
- 创建 HTTP 请求并在查询字符串上发送此参数
前 2 steph 运行 完美,但在发送 HTTPRequest 后主线程退出应用程序,因为不等待响应。
这是我的 HTTPRequest 代码:(我必须使用 CoreFoundation Framework,因为 Foundation Framework 中的 NSConnection 不是 运行)
for (int i = 0; i < [_arrayOfSerial count]; i++) {
CFStringRef urlFirst = CFSTR("http://192.168.30.9:88/virtualBadge.aspx?token=");
CFStringRef token =(CFStringRef)_codicePWD;
CFStringRef urlSecond = CFSTR("&serial=");
CFStringRef serial = (CFStringRef) [_arrayOfSerial objectAtIndex:i];
NSLog(@"URL: %@%@%@%@", urlFirst,token,urlSecond,serial);
CFStringRef strs[4];
strs[0] = urlFirst;
strs[1] = token;
strs[2] = urlSecond;
strs[3] = serial;
CFArrayRef urlArray = CFArrayCreate(kCFAllocatorDefault, (void*)strs, 4, &kCFTypeArrayCallBacks);
CFStringRef urlCompleta = CFStringCreateByCombiningStrings(kCFAllocatorDefault, urlArray, CFSTR(""));
NSLog(@"Url: %@",urlCompleta);
CFURLRef myURL = CFURLCreateWithString(kCFAllocatorDefault, urlCompleta, NULL);
CFStringRef headerFieldName = CFSTR("host");
CFStringRef headerFieldValue = CFSTR("192.168.30.9");
CFStringRef requestMethod = CFSTR("GET");
CFHTTPMessageRef myRequest =CFHTTPMessageCreateRequest(kCFAllocatorDefault, requestMethod, myURL, kCFHTTPVersion1_1);
CFHTTPMessageSetHeaderFieldValue(myRequest, headerFieldName, headerFieldValue);
CFDataRef mySerializedRequest = CFHTTPMessageCopySerializedMessage(myRequest);
if(CFHTTPMessageIsRequest(myRequest)){
NSLog(@"Is a Request: OK");
if(CFHTTPMessageIsHeaderComplete(myRequest)){
NSLog(@"Header OK");
}
}
CFReadStreamRef myReadStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, myRequest);
CFOptionFlags events = kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered | kCFStreamEventCanAcceptBytes | kCFStreamEventNone | kCFStreamEventOpenCompleted;
CFStreamClientContext dataStreamContext = {
0,
self,
(void *(*)(void *info))CFRetain,
(void (*)(void *info))CFRelease,
(CFStringRef (*)(void *info))CFCopyDescription
};
if(CFReadStreamSetClient(myReadStream, events, EvenCallBack, &dataStreamContext)){
CFReadStreamScheduleWithRunLoop(myReadStream, CFRunLoopGetMain(), kCFRunLoopCommonModes);
}
if(CFReadStreamOpen(myReadStream)){
NSLog(@"Stream Open - ");
}
NSString *messReq = [[[NSString alloc] initWithData:(NSData*)mySerializedRequest encoding:NSASCIIStringEncoding] autorelease];
CFRelease(myRequest);
CFRelease(myURL);
CFRelease(urlArray);
CFRelease(urlCompleta);
CFRelease(myReadStream);
NSLog(@"Serialized Request: %@", messReq);
// NSLog(@"Request Send");
}
"EvenCallBack" 函数永远不会调用,因为主线程退出:
int main(int argc, const char * argv[])
{
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
Demone* demone = [[Demone alloc] init]; //This is the class that start all process
[demone startDemone]; //Function start process
[demone release];
}
NSLog(@"Exit");
return 0;
}
我的错误在哪里?
为什么应用从不等待响应?
你启动了恶魔,它可能会进入后台。在它完成之前你释放它。比它没了...
来自 documentation 我的意思是您需要设置一个客户端,然后等待来自流的响应。您的应用在启动恶魔后就退出了。
您可以在 main 中使用 while 循环并检查流是否完成。然后就可以退出了。只要你在 while 循环中给 runloop 计算时间,例如 [NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:3]];
。