如何使用NSInputStream和NSOutputStream
我正试图在iPhone之间创build一个简单的多人回合制游戏。 现在我想要做的就是将一些string传递给我的方法,并让方法通过NSOutputStream
发送string。 我想我已经使用NSNetServiceBrowser
正确连接了我的NSNetServiceBrowser
。 一旦他们连接,我的NSNetServiceDelegate
有netService:didAcceptConnectionWithInputStream:outputStream:
叫,这应该给我我的I / O NSStream对。 我的方法如下所示:
-(void)netService:(NSNetService *)sender didAcceptConnectionWithInputStream:(NSInputStream *)inputStream outputStream:(NSOutputStream *)outputStream{ [self.myNet getInputStream:&inputStream outputStream:&outputStream]; self.inStream = inputStream; self.outStream = outputStream; [self.inStream setDelegate:self]; [self.inStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [self.inStream open]; }
我想我已经正确设置了NSInputStream。 我也有一个NSStream实现stream:handleEvent:
的委托stream:handleEvent:
它看起来像这样:
-(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{ NSInputStream *inStream = (NSInputStream *)aStream; BOOL shouldClose = NO; switch(eventCode) { case NSStreamEventEndEncountered: shouldClose = YES; // If all data hasn't been read, fall through to the "has bytes" event if(![inStream hasBytesAvailable]) break; case NSStreamEventHasBytesAvailable: ; // We need a semicolon here before we can declare local variables uint8_t *buffer; NSUInteger length; BOOL freeBuffer = NO; // The stream has data. Try to get its internal buffer instead of creating one if(![inStream getBuffer:&buffer length:&length]) { // The stream couldn't provide its internal buffer. We have to make one ourselves buffer = malloc(BUFFER_LEN * sizeof(uint8_t)); freeBuffer = YES; NSInteger result = [inStream read:buffer maxLength:BUFFER_LEN]; if(result < 0) { // error copying to buffer break; } length = result; } // length bytes of data in buffer if(freeBuffer) free(buffer); break; case NSStreamEventErrorOccurred: // some other error shouldClose = YES; break; case NSStreamEventHasSpaceAvailable: break; case NSStreamEventNone: break; case NSStreamEventOpenCompleted: break; } if(shouldClose){ [inStream close]; } }
我从这个页面获取了这个代码。 在那个代码中, aStream
应该是self.inStream
。 我已经看了一些描述为NSOutputStream
做什么的页面,但是他们没有一个像我这样的初学者。 我有几个问题。 首先,我如何设置一个传递数据的方法( NSData
或NSString
),并通过self.outStream
发送出去。 我更喜欢解释代码的答案,而不是仅仅把它给我。 其次,我应该打开netService:didAcceptConnectionWithInputStream:outputStream:
两个我的streamnetService:didAcceptConnectionWithInputStream:outputStream:
我也应该scheduleInRunLoop
NSOutputStream
self.outStream`。 最后,我做错了什么?
感谢您的回答。 这也是我的第一个问题,所以任何build设性的批评都是受欢迎的。
要写入输出stream,检查stream具有可用空间并使用写入数据
- (NSInteger)write:(const uint8_t *)buffer maxLength:(NSUInteger)length
所以,代码可能如下。
if(self.outStream.hasSpaceAvailable)[self.outStream write:... maxLength:];
如果输出stream稍后没有可用空间
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
输出stream委托的方法将被调用eventCode = NSStreamEventHasSpaceAvailable。
您应该打开输出stream并将其排定在netService:didAcceptConnectionWithInputStream:outputStream中,或者当您收到inputstream的NSStreamEventOpenCompleted时。 两者都可以。
如果你不想写块线程,你需要准备队列。
所以代码如下
NSMutableData * uQueue; NSInputStream * uIStream; NSOutputStream * uOStream; : : : uIStream.delegate = self; uOStream.delegate = self; [uIStream scheduleInRunLoop:NSRunLoop.currentRunLoop forMode:NSDefaultRunLoopMode]; [uOStream scheduleInRunLoop:NSRunLoop.currentRunLoop forMode:NSDefaultRunLoopMode]; [uIStream打开]; [uOStream open]; uQueue = NSMutableData.data; : : : - (void) 发送 {if(uQueue.length) {NSInteger wLength = [uOStream write:(const uint8_t *)uQueue.bytes maxLength:uQueue.length]; if(wLength> 0)[uQueue replaceBytesInRange:NSMakeRange(0,wLength)withBytes:NULL length:0]; } } - (void) 写:(NSData的*)p {[uQueue appendData:p]; 如果(uOStream.hasSpaceAvailable)[self send]; } - (void) stream:(NSStream *)PS 的handleEvent:(NSStreamEvent)p {switch(p) { : : : 大小写NSStreamEventHasSpaceAvailable: [self send]; 打破; } }