我正在尝试在iPhone之间创建一个简单的基于多人回合的游戏。现在,我要做的就是将一些字符串传递给我的方法,然后让该方法通过NSOutputStream
发送字符串。我想我已经使用NSNetServices
正确连接了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:
看起来像这样:
-(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];
}
}
我从this page中获取了该代码。在该代码中,
aStream
应该是self.inStream
。我看过描述NSOutputStream
的页面,但是似乎没有一个页面适合我这样的初学者。我有几个问题。首先,我该如何设置传入数据的方法(NSData
或NSString
),然后通过self.outStream
将数据发送出去。我希望有一个解释代码的答案,而不是仅仅给我。其次,我应该在netService:didAcceptConnectionWithInputStream:outputStream:
中打开两个流,还是应该在scheduleInRunLoop
self.outStream`中对NSOutputStream
进行编码。最后,我做错了什么吗?感谢您的回答。这也是我的第一个问题,因此欢迎任何建设性的批评。
最佳答案
要写入输出流,请检查流是否有可用空间,并使用
-(NSInteger)write:(const uint8_t *)buffer maxLength:(NSUInteger)length
因此,代码可能如下所示。
如果(self.outStream.hasSpaceAvailable)[self.outStream写入:... maxLength:];
如果输出流没有可用空间,请稍后
-(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
将使用eventCode = NSStreamEventHasSpaceAvailable调用输出流的委托的方法。
您应该打开输出流并将其安排在netService:didAcceptConnectionWithInputStream:outputStream中,或者在收到输入流的NSStreamEventOpenCompleted时进行安排。都可以。
如果您不想编写块线程,则需要准备队列。
所以代码就像下面
NSMutableData * uQueue;
NSInputStream * uIStream;
NSOutputStream * uOStream;
:
:
:
uIStream.delegate =自我;
uOStream.delegate =自我;
[uIStream scheduleInRunLoop:NSRunLoop.currentRunLoop forMode:NSDefaultRunLoopMode];
[uOStream scheduleInRunLoop:NSRunLoop.currentRunLoop forMode:NSDefaultRunLoopMode];
[uIStream open];
[uOStream打开];
uQueue = NSMutableData.data;
:
:
:
-(无效)
发送
{如果(uQueue.length)
{NSInteger wLength = [uOStream写入:(const uint8_t *)uQueue.bytes maxLength:uQueue.length];
if(wLength> 0)[uQueue replaceBytesInRange:NSMakeRange(0,wLength)withBytes:NULL length:0];
}
}
-(无效)
写:(NSData *)p
{[uQueue appendData:p];
如果(uOStream.hasSpaceAvailable)[self Send];
}
-(无效)
流:(NSStream *)pS
handleEvent:(NSStreamEvent)p
{开关(p)
{
:
:
:
情况NSStreamEventHasSpaceAvailable:
[自我发送];
打破;
}
}
关于ios - 如何使用NSInputStream和NSOutputStream,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23186152/