2017-12-01 1 views
0

私はすべてのコードを試しました。このコードを使用して、connect ipv6 networkをconnect XMPPに使用できました。ipv4ネットワークのXMPP接続問題

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

上記の方法は、常に両方のネットワークでipv6を接続します。

私は[asyncSocket setPreferIPv4OverIPv6:NO]をコミットします。 ipv4.pleaseがme.iは、両方のネットワークを接続する助け接続しないよりも、私はこのコードを使用しipv6.if IPv4ネットワークが、中に適切な仕事よりも、このコードは

+0

あなたはこの行を書いています - 'asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:xmppQueue];'あなたのコードには?クラスまたはファイルを意味しますか? –

+0

XMPPStream.mファイル内の@NiravKotecha – iOS

+0

実際に私は 'setPreferIPv4OverIPv6'メソッドを呼び出して正常に実行していません。私たちはipv6を持っていないので、 'asyncSocket.IPv4PreferredOverIPv6 = NO'を追加した後に –

答えて

0

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

どうすればstateIndexを取得できますか?宣言されていない識別子 'stateIndex'の使用 – iOS

+0

int stateIndex = 0; –

+0

このリンクからxmppフレームワークをダウンロードすることができます - https://www.dropbox.com/s/iobkfdjy2q0png5/XMPP.zip?dl=0 –