HttpRequest 的 CFReadStream

CFReadStream For HttpRequest

我必须开发一个终端工具应用程序以每 20 秒创建一个守护进程 运行。

这个Deamon只做这一步

前 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]];