2010-06-18 164 views
0

我一直在與CFNetwork合作爲iPad創建一個客戶端應用程序,它是一個小應用程序,沒有任何幻想。爲什麼DataCallBack方法在後臺偵聽未被調用?

這是我如何創建連接到服務器(在Windows中運行)。

- (void) startConnection 
{ 
    char ip[] = "192.168.0.244"; 
    NSString *ipAddress = [[NSString alloc] initWithCString:ip]; 

    /* Build our socket context; this ties an instance of self to the socket */ 
    CFSocketContext CTX = { 0, self, NULL, NULL, NULL }; 

    /* Create the server socket as a TCP IPv4 socket and set a callback */ 
    /* for calls to the socket's lower-level connect() function */ 
    TCPClient = CFSocketCreate(NULL, PF_INET, SOCK_STREAM, IPPROTO_TCP, 
           kCFSocketDataCallBack, (CFSocketCallBack)DataCallBack, &CTX); 

    if (TCPClient == NULL) 
     return; 

    /* Set the port and address we want to listen on */ 
    struct sockaddr_in addr; 
    memset(&addr, 0, sizeof(addr)); 
    addr.sin_len = sizeof(addr); 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(PORT);// PORT = 5001 
    addr.sin_addr.s_addr = inet_addr([ipAddress UTF8String]); 

    CFDataRef connectAddr = CFDataCreate(NULL, (unsigned char *)&addr, sizeof(addr)); 
    CFSocketConnectToAddress(TCPClient, connectAddr, -1); 
    CFRunLoopSourceRef sourceRef = 
    CFSocketCreateRunLoopSource(kCFAllocatorDefault, TCPClient, 0); 
    CFRunLoopAddSource(CFRunLoopGetCurrent(), sourceRef, kCFRunLoopCommonModes); 
    CFRelease(sourceRef); 
    CFRunLoopRun(); 
} 

正如您所看到的,當我創建服務器套接字時,我註冊了一個回調以偵聽來自服務器的傳入數據。

然後我使用CFRunLoopAddSource(...)和CFRunLoopRun()方法在後臺偵聽此回調。

現在,這是它的外觀我的發送方法

- (void) send 
{ 
    if (TCPClient == NULL) 
     return; 

    Byte byteData[3]; 
    for (int i = 1; i <= 25; i++) { 
     receivedLastAnswer = NO; 
     globalPos = i; 
     byteData[0] = i; 
     byteData[1] = 4; 
     byteData[2] = 0; 
     int len = 3;//strlen(byte)+1;    
     CFDataRef refData = CFDataCreate(kCFAllocatorDefault, byteData, len); 
     CFSocketSendData(TCPClient, NULL, refData, 0); 
     while (!receivedLastAnswer) { 
      //this while is to wait until a response is send by the server 
     } 
    } 
} 

我想要做的就是發送命令到服務器(3個字節數組,你看到的是命令),然後等待服務器在發送下一個命令之前做出響應,爲此,我使用了一段時間,變量「receivedLastAnswer」是一個標誌,當我的DataCallBack方法被調用時被設置,所以如果服務器響應,回調被調用,它將該標誌設置爲真因此該時間退出並且下一個命令被髮送。

當然,這不是我打算如何離開代碼,這只是爲了測試,看看它是否有效,以後我將不得不另外添加一個條件到一個超時條件,以防服務器根本沒有迴應。

現在,我的問題是,我的應用程序,客戶端,沒有觸發回調方法,因此它只是無限循環;我認爲不發起回調的原因是因爲應用程序在while循環中忙碌,事實上,如果我刪除循環,回調被觸發,但這對我沒有意義,因爲不是回調方法在不同的線程上運行(不是CFRunLoopRun()的目的?),並且因爲它運行在不同的線程中,所以主線程應該在一個循環中或者我完全誤解了它的工作方式?另外,我嘗試不使用while循環,但使用Sleep()函數,但它是一樣的,沒有回調被觸發。

你有任何想法,爲什麼這可能發生或我怎麼能做到這一點,

感謝。

回答

0

嗯,我認爲在行動我的數據回調不會被稱爲如果主線程忙或阻塞,所以我做的是離開回調方法的主線程,並把我的發送方法在另一個線程,它的工作實際上相當不錯,但是如果還有其他方法,我仍然在遊蕩,但現在它滿足了我的需求,所以我會堅持下去。

相關問題