2011-10-03 59 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

相关问题