2012-07-12 116 views
1

我正在嘗試使用CFStream獲得簡單的HTTP通信,但是使用下面的代碼,即使給出無效的URL(wwwww.yahoo.com),我仍然可以獲得連接成功。通過CFStream的HTTP請求

有人能指點我這個代碼有什麼問題嗎?我希望調用CFReadStreamOpen()失敗,但即使URL不好,它仍然成功。

我一直無法找到一個簡單的CFNetwork例子,它可以在ARC上運行HTTP(不使用NSURL)。如果有人知道這樣的示例代碼,請讓我知道。

- (void) test 
{ 

    CFStringRef m_host = CFStringCreateWithCString(NULL, "wwwww.yahoo.com", kCFStringEncodingASCII); 

    int m_port = 80; 
    CFHostRef host; 

    NSLog(@"Attempting to (re)connect to %@:%d", m_host, m_port); 

    { 

     CFReadStreamRef  m_in = NULL; 
     CFWriteStreamRef m_out = NULL; 

     host = CFHostCreateWithName(kCFAllocatorDefault, (CFStringRef)m_host); 
     if (!host) 
     { 
      NSLog(@"Error resolving host %@", m_host); 
     } 

     CFStreamCreatePairWithSocketToCFHost(kCFAllocatorDefault, host , m_port, &m_in, &m_out); 
     CFRelease(host); 

     CFStreamClientContext context = {0, nil,nil,nil,nil}; 


     if (CFReadStreamSetClient(m_in, kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, networkReadEvent, &context)) 
     { 
      CFReadStreamScheduleWithRunLoop(m_in, CFRunLoopGetCurrent(),kCFRunLoopCommonModes); 
     } 

     if (CFWriteStreamSetClient(m_out, kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, networkWriteEvent, &context)) 
     { 
      CFWriteStreamScheduleWithRunLoop(m_out, CFRunLoopGe tCurrent(),kCFRunLoopCommonModes); 
     }   

     BOOL success = CFReadStreamOpen(m_in); 
     CFErrorRef error = CFReadStreamCopyError(m_in); 
     if (!success || (error && CFErrorGetCode(error) != 0)) 
     { 
      NSLog(@"Connect error %s : %ld", CFErrorGetDomain(error), CFErrorGetCode(error)); 
      [NSThread sleepForTimeInterval:5.0]; 
     } 

     success = CFWriteStreamOpen(m_out); 
     error = CFReadStreamCopyError(m_in); 
     if (!success || (error && CFErrorGetCode(error) != 0)) 
     { 
      NSLog(@"Connect error %s : %d", CFErrorGetDomain(error), CFErrorGetCode(error)); 
      [NSThread sleepForTimeInterval:5.0]; 
     } 
     else 
     { 
      NSLog(@"Connected"); 
     } 

    } 
} 

回答

0

對於異步代碼(如您的),您需要設置委託並在那裏捕獲錯誤。退房http://iphonedevsdk.com/forum/iphone-sdk-development/17542-cfstream-catch-error-in-connection.html

根據蘋果開發人員網站的說法,「如果流可以在不阻塞的情況下在後臺打開,則此函數總是返回true。」這意味着打開流的請求會在不同的線程中發送出去,因此當您調用該函數並在後臺線程上啓動連接進程時,該函數將返回true。所有對各個流的讀/寫調用都會阻塞,直到後臺線程完成打開流。如果您在「CFReadStreamOpen(m_in);」上設置了一個斷點,您將能夠看到此內容。並查看該單行執行後會發生什麼。希望這回答你的問題。