ipv4网络中的XMPP连接问题

时间:2017-12-01 06:31:13

标签: ios objective-c xmppframework

我尝试了所有的code.i使用此代码允许连接ipv6网络连接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网络中正常工作但是没有连接ipv6.if我使用这个代码而不是连接ipv4.please帮助我。我想连接两个网络..

1 个答案:

答案 0 :(得分: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;
}