gpt4 book ai didi

objective-c - 如何在 iOS 中的同一个运行循环中打开多个套接字流?

转载 作者:行者123 更新时间:2023-11-28 17:42:22 25 4
gpt4 key购买 nike

在我的程序中,我在运行循环上安排了一个读写流,并且工作正常。稍后在程序中我想打开另一个流,读取或写入取决于角色然后我想将它安排到同一台服务器的同一个运行循环,但那是行不通的。我在新创建的流上调用了 open,但我没有看到任何 NSStreamEventOpenCompleted 事件进入新打开的流。以下是我如何创建流和委托(delegate)的实现来处理事件:

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];
}
}

委托(delegate)实现:

- (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 opened 和 imageInStream opened 被打印出来。我在 scheduleInRunLoop 中发现:对于 imageInStream 和 imageOutStream,如果我使用 mainRunLoop 而不是 currentRunLoop,我可以看到打开的流打印出来,但即使这样,发送和接收仍然有问题。我在安排流时做错了什么吗?或者如果我想创建多个套接字流,我是否必须使用 scheduleInRunLoop 以外的其他方法。感谢您的帮助。

最佳答案

首先,我将在 -stream:handleEvent 的顶部添加无条件日志记录:例如 NSLog(@"stream %@ got event %x", theStream, (unsigned)streamEvent);。这将告诉您是否收到您未处理的事件,我怀疑您(某种程度上)正在处理。

NSStream docs ,

Stream Event Constants

One or more of these constants may be sent to the delegate as a bit field in the second parameter of stream:handleEvent:.

如果是位域,则无法轻松打开。它可能是 3 (NSStreamEventOpenCompleted|NSStreamEventHasBytesAvailable),这意味着流已打开并且有数据可供读取。

简单的修复看起来像这样

if (streamEvent&NSStreamEventOpenCompleted) {
...
}

if (streamEvent&NSStreamEventHasBytesAvailable) {
...
}

...

关于objective-c - 如何在 iOS 中的同一个运行循环中打开多个套接字流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7639427/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com