iosiphonesocketstcpgcdasyncsocket

Creating p2p connection iOS


Okay. So I have been trying to connect devices p2p with streams for a week. Still no result and i am getting crazy and desperate. Please Don't send me to Ray Wenderlich tutorial and GCD wiki or to CFStream Guide as i have surfed it to the holes.

So 1) Variant Here i

  1. Get Ip Of My device
  2. Manually input ip in text field of other device
  3. Init network communication on one device.
  4. Error - connecting to host.

     + (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]; if (!website) { NSLog(@"%@ is not a valid URL"); return; } CFReadStreamRef readStream; CFWriteStreamRef writeStream; CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)[website host], 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]; [inputStream open]; [outputStream open];

    }

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

    NSLog(@"stream event %lu", streamEvent);

    switch (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");
    

    }

    }

Variant 2 with GCD. 1. Same 2. Set both devices to listen to input

+(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) Tried to connect with manually inputting 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) Result nothing - i did put several breaks on every delegate function =NOTHING.

Omg - i solved this task on Android in 20 minutes! But here it just drives crazy. Tried in several networks. Thrue 3g, home wifi. Please someone help!


Solution

  • The problem I can see from all of your various attempts is that you are storing the socket in a local variable - this means that once the method exits it will be released and no communications will be possible on that socket.

    You need to store your socket references in strong properties.

    I have created an example application using CocoaAsyncSocket that demonstrates listening for connections and making a connection along with tracking the connection state through properties holding the sockets.

    It is available here https://github.com/paulw11/SocketDemo