2011-10-03 61 views
1

在我的程序中,我有一個在runloop上預定的讀寫流,並且工作正常。在程序的後面,我想打開另一個流,要麼讀取或寫入取決於角色,然後我想安排它到同一個runloop到同一臺服務器,但這是行不通的。我打開了新創建的流,但是我沒有看到任何NSStreamEventOpenCompleted事件來到新打開的流。以下是我創建流和委託的實現來處理事件:如何在iOS中的同一個runloop上打開多個套接字流?

Controller.m或者

- (void)initNetworkCommunication:(NSString *)ip_address withPort:(NSInteger)port role:(network_role_t)role 
{ 
    CFReadStreamRef readStream; 
    CFWriteStreamRef writeStream; 

    NSLog(@"server IP: %@, port: %d, role: %d", ip_address, port, role); 
    if (port != 8080) { 
     if (role == HOST) { 
      CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)ip_address, port, NULL, &writeStream); 
      imageOutStream = (NSOutputStream *)writeStream; 
      [imageOutStream setDelegate:self]; 
      [imageOutStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
      [imageOutStream open]; 
      NSLog(@"host connected"); 
     } else if (role == CLIENT) { 
      CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)ip_address, port, &readStream, NULL); 
      imageInStream = (NSInputStream *)readStream; 
      [imageInStream setDelegate:self]; 
      [imageInStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
      [imageInStream open]; 
      NSLog(@"client connected"); 
     } 
    } else { 
     CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)ip_address, port, &readStream, &writeStream); 
     inputStream = (NSInputStream *)readStream; 
     outputStream = (NSOutputStream *)writeStream; 
     [inputStream setDelegate:self]; 
     [outputStream setDelegate:self]; 
     [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
     [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
     [inputStream open]; 
     [outputStream open]; 
    } 
} 

委託執行:

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent 
{ 

    switch (streamEvent) { 
     case NSStreamEventHasBytesAvailable: 
      if (theStream == inputStream) { 
       /* send regular data */ 
      } else if (theStream == imageInStream) { 
       /* send raw data */ 
      } 
     break; 
     case NSStreamEventOpenCompleted: 
      if (theStream == imageOutStream) { 
       NSLog(@"imageOutStream opened"); 
      } else if (theStream == imageInStream) { 
       NSLog(@"imageInStream opened"); 
      } 
     break; 
     case NSStreamEventErrorOccurred: 
      //NSError *theError = [theStream streamError]; 
      NSLog(@"Socket error string: %@", [[theStream streamError] localizedDescription]); 
     break; 
    } 
} 

所以我看不出imageOutStream開imageInStream打開時,他們連接到服務器。我發現在scheduleInRunLoop中:對於imageInStream和imageOutStream,如果我使用mainRunLoop而不是currentRunLoop,我可以看到打開的流打印出來,但即使如此,發送和接收仍然有問題。我在安排流時做錯了什麼?或者,如果我想創建多個套接字流,則必須使用scheduleInRunLoop以外的其他方法。謝謝您的幫助。

回答

0

首先,我要在-stream的頂部添加無條件記錄:爲handleEvent:像NSLog(@"stream %@ got event %x", theStream, (unsigned)streamEvent);。這會告訴你,如果你正在處理你沒有處理的事件,我懷疑你(有點)。

NSStream docs

流事件常量

一個或多個這些常數可以被髮送到委託作爲位字段在流的第二個參數:的handleEvent :.

如果是位域,則無法輕鬆開啓。它可能是3(NSStreamEventOpenCompleted|NSStreamEventHasBytesAvailable)這意味着流已打開有數據可供閱讀。

的簡單的解決看起來是這個

if (streamEvent&NSStreamEventOpenCompleted) { 
    ... 
} 

if (streamEvent&NSStreamEventHasBytesAvailable) { 
    ... 
} 

... 
+0

感謝您的答覆等。原來我是從另一個線程調用initNetworkCommunication,所以它使用線程的runloop。我改成了mainRunLoop,這個東西正在工作。 – Billy

相關問題