好的。所以我一直在尝试将设备 p2p 与流连接一个星期。仍然没有结果,我变得疯狂和绝望。请不要将我发送到 Ray Wenderlich 教程和 GCD wiki 或 CFStream 指南,因为我已经将其浏览到漏洞。
所以 1) 变体在这里
- 获取我的设备的 IP
- 在其他设备的文本字段中手动输入 ip
- 在一台设备上初始化网络通信。
错误 - 连接到主机。
+ (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; 如果 (![urlStr isEqualToString:@""]) { NSURL *网站 = [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]; [outputStream setDelegate:self]; [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [输入流打开]; [输出流打开];
- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
NSLog(@"流事件 %lu", streamEvent);
切换(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) 没有结果 - 我确实在每个委托(delegate)函数上设置了几次中断 =NOTHING。
天哪 - 我在 Android 上用了 20 分钟就解决了这个任务!但在这里它只会让人发疯。在几个网络中尝试过。通过 3g,家庭 wifi。请有人帮忙!
最佳答案
从您的所有尝试中我可以看到的问题是您将套接字存储在本地变量中 - 这意味着一旦该方法退出,它将被释放,并且该套接字上将无法进行通信。
您需要将套接字引用存储在 strong
属性中。
我使用 CocoaAsyncSocket 创建了一个示例应用程序,该应用程序演示了监听连接和建立连接,以及通过持有套接字的属性跟踪连接状态。
关于ios - 创建 p2p 连接 iOS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27598325/