2017-12-01 1 views
0

Ich versuchte alle code.i verwendet diesen Code, um das connect ipv6-Netzwerk für connect XMPP zu ermöglichen.XMPP connect Problem in ipv4-Netzwerk

asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:xmppQueue]; 
[asyncSocket setPreferIPv4OverIPv6:NO]; 

- (void)setPreferIPv4OverIPv6:(BOOL)flag 
{ 
    // Note: YES means kPreferIPv6 is OFF 

    dispatch_block_t block = ^{ 

     if (flag) 
      config &= ~kPreferIPv6; 
     else 
      config |= kPreferIPv6; 
    }; 

    if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) 
     block(); 
    else 
     dispatch_async(socketQueue, block); 
} 

- (BOOL)connectWithAddress4:(NSData *)address4 address6:(NSData *)address6 error:(NSError **)errPtr 
{ 
    LogTrace(); 

    NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); 

    LogVerbose(@"IPv4: %@:%hu", [[self class] hostFromAddress:address4], [[self class] portFromAddress:address4]); 
    LogVerbose(@"IPv6: %@:%hu", [[self class] hostFromAddress:address6], [[self class] portFromAddress:address6]); 

    // Determine socket type 

    BOOL preferIPv6 = (config & kPreferIPv6) ? YES : NO; 

    BOOL useIPv6 = ((preferIPv6 && address6) || (address4 == nil)); 

    // Create the socket 

    __block int socketFD; 
    __block NSData *address; 
    __block NSData *connectInterface; 

    if (useIPv6) 
    { 
     LogVerbose(@"Creating IPv6 socket"); 

     socket6FD = socket(AF_INET6, SOCK_STREAM, 0); 

     socketFD = socket6FD; 
     address = address6; 
     connectInterface = connectInterface6; 
    } 
    else 
    { 
     LogVerbose(@"Creating IPv4 socket"); 

     socket4FD = socket(AF_INET, SOCK_STREAM, 0); 

     socketFD = socket4FD; 
     address = address4; 
     connectInterface = connectInterface4; 
    } 

    if (socketFD == SOCKET_NULL) 
    { 
     if (errPtr) 
      *errPtr = [self errnoErrorWithReason:@"Error in socket() function"]; 

     return NO; 
    } 

    // Bind the socket to the desired interface (if needed) 

    if (connectInterface) 
    { 
     LogVerbose(@"Binding socket..."); 

     if ([[self class] portFromAddress:connectInterface] > 0) 
     { 
      // Since we're going to be binding to a specific port, 
      // we should turn on reuseaddr to allow us to override sockets in time_wait. 

      int reuseOn = 1; 
      setsockopt(socketFD, SOL_SOCKET, SO_REUSEADDR, &reuseOn, sizeof(reuseOn)); 
     } 

     const struct sockaddr *interfaceAddr = (const struct sockaddr *)[connectInterface bytes]; 

     int result = bind(socketFD, interfaceAddr, (socklen_t)[connectInterface length]); 
     if (result != 0) 
     { 
      if (errPtr) 
       *errPtr = [self errnoErrorWithReason:@"Error in bind() function"]; 

      return NO; 
     } 
    } 

    // Prevent SIGPIPE signals 

    int nosigpipe = 1; 
    setsockopt(socketFD, SOL_SOCKET, SO_NOSIGPIPE, &nosigpipe, sizeof(nosigpipe)); 

    // Start the connection process in a background queue 

    int aConnectIndex = connectIndex; 

// dispatch_queue_t globalConcurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
// dispatch_async(globalConcurrentQueue, ^{ 

     int result = connect(socketFD, (const struct sockaddr *)[address bytes], (socklen_t)[address length]); 
     if (result != 0) { 

      socket6FD = SOCKET_NULL; 
      socket4FD = socket(AF_INET, SOCK_STREAM, 0); 

      socketFD = socket4FD; 
      address = address4; 
      connectInterface = connectInterface4; 

      result = connect(socketFD, (const struct sockaddr *)[address bytes], (socklen_t)[address length]); 
     } 
    //}); 

    LogVerbose(@"Connecting..."); 

    return YES; 
} 

über diese Methode immer verbinden ipv6 in beiden Netzwerken.

wenn ich comment [asyncSocket setPreferIPv4OverIPv6: NEIN]; dieser Code als richtige Arbeit in IPv4-Netzwerk, aber keine Verbindung ipv6.if ich diesen Code verwendet als ipv4.please me.i sowohl Netzwerk verbinden nicht verbinden helfen wollen ..

+0

wo Sie diese Zeile schreiben - 'asyncSocket = [[GCDAsyncSocket Alloc] initWithDelegate: selbst DelegateQueue: XmppQueue];' in Ihrem Code? bedeutet in welcher Klasse oder welcher Datei? –

+0

@ NiravKotecha in XMPPStream.m Datei – iOS

+0

tatsächlich ich rufe nicht 'setPreferIPv4OverIPv6' Methode und läuft erfolgreich. weil wir nicht ipv6 haben –

Antwort

0

versuchen, diese Methode der connectWithAddress4...

- (BOOL)connectWithAddress4:(NSData *)address4 address6:(NSData *)address6 error:(NSError **)errPtr 
{ 
    LogTrace(); 

    NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); 

    LogVerbose(@"IPv4: %@:%hu", [[self class] hostFromAddress:address4], [[self class] portFromAddress:address4]); 
    LogVerbose(@"IPv6: %@:%hu", [[self class] hostFromAddress:address6], [[self class] portFromAddress:address6]); 

    // Determine socket type 

    BOOL preferIPv6 = (config & kPreferIPv6) ? YES : NO; 

    BOOL useIPv6 = ((preferIPv6 && address6) || (address4 == nil)); 

    // Create the socket 

    int socketFD; 
    NSData *address; 
    NSData *connectInterface; 

    if (useIPv6) 
    { 
     LogVerbose(@"Creating IPv6 socket"); 

     socket6FD = socket(AF_INET6, SOCK_STREAM, 0); 

     socketFD = socket6FD; 
     address = address6; 
     connectInterface = connectInterface6; 
    } 
    else 
    { 
     LogVerbose(@"Creating IPv4 socket"); 

     socket4FD = socket(AF_INET, SOCK_STREAM, 0); 

     socketFD = socket4FD; 
     address = address4; 
     connectInterface = connectInterface4; 
    } 

    if (socketFD == SOCKET_NULL) 
    { 
     if (errPtr) 
      *errPtr = [self errnoErrorWithReason:@"Error in socket() function"]; 

     return NO; 
    } 

    // Bind the socket to the desired interface (if needed) 

    if (connectInterface) 
    { 
     LogVerbose(@"Binding socket..."); 

     if ([[self class] portFromAddress:connectInterface] > 0) 
     { 
      // Since we're going to be binding to a specific port, 
      // we should turn on reuseaddr to allow us to override sockets in time_wait. 

      int reuseOn = 1; 
      setsockopt(socketFD, SOL_SOCKET, SO_REUSEADDR, &reuseOn, sizeof(reuseOn)); 
     } 

     const struct sockaddr *interfaceAddr = (const struct sockaddr *)[connectInterface bytes]; 

     int result = bind(socketFD, interfaceAddr, (socklen_t)[connectInterface length]); 
     if (result != 0) 
     { 
      if (errPtr) 
       *errPtr = [self errnoErrorWithReason:@"Error in bind() function"]; 

      return NO; 
     } 
    } 

    // Prevent SIGPIPE signals 

    int nosigpipe = 1; 
    setsockopt(socketFD, SOL_SOCKET, SO_NOSIGPIPE, &nosigpipe, sizeof(nosigpipe)); 

    // Start the connection process in a background queue 

    int aStateIndex = stateIndex; 
    __weak GCDAsyncSocket *weakSelf = self; 

    dispatch_queue_t globalConcurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    dispatch_async(globalConcurrentQueue, ^{ 
    #pragma clang diagnostic push 
    #pragma clang diagnostic warning "-Wimplicit-retain-self" 

     int result = connect(socketFD, (const struct sockaddr *)[address bytes], (socklen_t)[address length]); 

     __strong GCDAsyncSocket *strongSelf = weakSelf; 
     if (strongSelf == nil) return_from_block; 

     if (result == 0) 
     { 
      dispatch_async(strongSelf->socketQueue, ^{ @autoreleasepool { 

       [strongSelf didConnect:aStateIndex]; 
      }}); 
     } 
     else 
     { 
      NSError *error = [strongSelf errnoErrorWithReason:@"Error in connect() function"]; 

      dispatch_async(strongSelf->socketQueue, ^{ @autoreleasepool { 

       [strongSelf didNotConnect:aStateIndex error:error]; 
      }}); 
     } 

    #pragma clang diagnostic pop 
    }); 

    LogVerbose(@"Connecting..."); 

    return YES; 
} 
+0

Wie kann ich StateIndex bekommen. Verwendung der nicht deklarierten ID 'stateIndex' – iOS

+0

int stateIndex = 0; –

+0

Sie können xmpp Rahmen von diesem Link herunterladen - https://www.dropbox.com/s/iobkfdjy2q0png5/XMPP.zip?dl=0 –