【问题标题】:Creating p2p connection iOS创建 p2p 连接 iOS
【发布时间】:2015-02-20 07:04:25
【问题描述】:

好的。所以我一直在尝试将设备 p2p 与流连接一周。仍然没有结果,我变得疯狂和绝望。请不要将我发送到 Ray Wenderlich 教程和 GCD wiki 或 CFStream 指南,因为我已经浏览了它。

所以 1) 变体在这里我

  1. 获取我设备的 IP
  2. 在其他设备的文本字段中手动输入ip
  3. 在一台设备上启动网络通信。
  4. 错误 - 连接到主机。

     + (NSString *)getIPAddress {
    
     NSString *address = @"error";
     struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0;
    // retrieve the current interfaces - returns 0 on success
     success = getifaddrs(&interfaces);
     if (success == 0) {
     // Loop through linked list of interfaces
     temp_addr = interfaces;
      while(temp_addr != NULL) {
        if(temp_addr->ifa_addr->sa_family == AF_INET) {
        // Check if interface is en0 which is the wifi connection on the iPhone
           if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) {
                // Get NSString from C String
                address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
    
            }
    
        }
    
        temp_addr = temp_addr->ifa_next;
    }
     }
     // Free memory
    freeifaddrs(interfaces);
    return address;
    
    }
    
    • (void) initNetworkCommunication:(NSString*)ipToConnect { NSString *urlStr = ipToConnect; if (![urlStr isEqualToString:@""]) { NSURL *website = [NSURL URLWithString:urlStr]; 如果(!网站){ NSLog(@"%@ 不是一个有效的 URL"); 返回; } CFReadStreamRef 读取流; CFWriteStreamRef 写流; CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)[网站主机], 80, &readStream, &writeStream);

    NSInputStream *inputStream = (__bridge_transfer NSInputStream *)readStream; NSOutputStream *outputStream = (__bridge_transfer NSOutputStream *)writeStream; [inputStream setDelegate:self]; [输出流 setDelegate:self]; [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [输入流打开]; [输出流打开];

    }

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

    NSLog(@"流事件 %lu", streamEvent);

    切换(流事件){

    case NSStreamEventOpenCompleted:
        NSLog(@"Stream opened");
        break;
    case NSStreamEventHasBytesAvailable:
    
        if (theStream == inputStream) {
    
            uint8_t buffer[1024];
            int len;
    
            while ([inputStream hasBytesAvailable]) {
                len = [inputStream read:buffer maxLength:sizeof(buffer)];
                if (len > 0) {
    
                    NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
    
                    if (nil != output) {
    
                        NSLog(@"server said: %@", output);
                        //[self messageReceived:output];
    
                    }
                }
            }
        }
        break;
    
    
    case NSStreamEventErrorOccurred:
    
        NSLog(@"Can not connect to the host!");
        break;
    
    case NSStreamEventEndEncountered:
    
        [theStream close];
        [theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
     //   [theStream release];
        theStream = nil;
    
        break;
    default:
        NSLog(@"Unknown event");
    

    }

    }

带有 GCD 的变体 2。 1. 相同 2. 设置两台设备监听输入

+(void)listenSocket:(GCDAsyncSocket*)listenSocket
{

listenSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

NSError *error = nil;
if (![listenSocket acceptOnPort:80 error:&error])
{
    NSLog(@"I goofed: %@", error);
}

}

3) 尝试手动输入IP连接

 +(void)connectToDeviceWithIp:(NSString*)deviceIp andSend:(HSUserCard*)tempCard andSocket:(GCDAsyncSocket*)tempSocket
{

tempSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
NSError *err = nil;
if (![tempSocket connectToHost:deviceIp onPort:80 error:&err])
    NSLog(@"I goofed: %@", err);



[tempSocket writeData:[NSKeyedArchiver archivedDataWithRootObject:tempCard] withTimeout:-1 tag:1];
}

4) 没有任何结果 - 我确实在每个委托函数上都设置了几次中断 =NOTHING。

天哪 - 我在 20 分钟内在 Android 上解决了这个任务!但在这里它只会让人发疯。在几个网络中尝试过。通过 3g,家庭 wifi。请有人帮忙!

【问题讨论】:

  • 我可以送你一份格式指南吗?
  • 在所有情况下,您的问题是您将套接字作为局部变量存储在方法中,因此一旦方法退出,套接字就不再存在。您需要将它们作为属性存储在您的类中
  • 并非如此。正如我尝试的那样。像这样作为变量和属性。这只是从 ray wenderlich 的示例中提取的。在第二种情况下,如果您正确查看它们是属性并且我存储它们。寻找 self.tempSocket
  • 你确实传入了一个套接字,但是你立即为那个变量重新分配了一个新的套接字——即使它是一个参数,它仍然是一个局部变量,所以它会在类中释放方法退出。我没有看到“自我”。任何地方
  • 我使用 GCDAsyncSocket 创建了一个示例项目 - github.com/paulw11/SocketDemo/tree/master

标签: ios iphone sockets tcp gcdasyncsocket


【解决方案1】:

我从您的各种尝试中看到的问题是您将套接字存储在局部变量中 - 这意味着一旦方法退出,它将被释放,并且该套接字上将无法进行通信。

您需要将套接字引用存储在strong 属性中。

我已经使用 CocoaAsyncSocket 创建了一个示例应用程序,它演示了监听连接和建立连接以及通过保存套接字的属性跟踪连接状态。

这里有https://github.com/paulw11/SocketDemo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    • 1970-01-01
    相关资源
    最近更新 更多