XMPPFramewoerk支持IPv6

本文提供了一种解决iOS应用中IPv6连接问题的方法,并详细介绍了如何修改GCDAsyncSocket来支持IPv6及TLS,同时给出了处理服务器证书验证的具体步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前有一个博主写了一个支持IPv6的解决方案,地址为http://blog.youkuaiyun.com/xuxue1072/article/details/51481102
但是我使用他的 不能改写成功 总是报错 Can't assign requested address
所以我查找一些其他资料找到一些其它的改写方案
第一步 先把cocoaAsynocSocket更新到最新的,这可以从Github 上找到。最新的cocoaAsynocSocket不允许使用AutoStartTLS 所以如果你的XMPPframework 版本不是最新的,就需要把这句代码屏蔽掉。
第二步 更改GCDAsyncSocket;在GCDAsyncSocket.m文件的方法中 把
{
    if (res->ai_family == AF_INET)
    {
        // Found IPv4 address.
        // Wrap the native address structure, and add to results.
        
        NSData *address4 = [NSData dataWithBytes:res->ai_addr length:res->ai_addrlen];
        [addresses addObject:address4];
    }
    else if (res->ai_family == AF_INET6)
    {
        // Fixes connection issues with IPv6
        // https://github.com/robbiehanson/CocoaAsyncSocket/issues/429#issuecomment-222477158
        
        // Found IPv6 address.
        // Wrap the native address structure, and add to results.
        
        struct sockaddr_in6 *sockaddr = (struct sockaddr_in6 *)res->ai_addr;
        in_port_t *portPtr = &sockaddr->sin6_port;
        if ((portPtr != NULL) && (*portPtr == 0)) {
                *portPtr = htons(port);
        }

        NSData *address6 = [NSData dataWithBytes:res->ai_addr length:res->ai_addrlen];
        [addresses addObject:address6];
    }
}
换成
for (res = res0; res; res = res->ai_next)
{
    if (res->ai_family == AF_INET)
    {
        // Found IPv4 address.
        // Wrap the native address structure, and add to results.
        
        if (((struct sockaddr_in *)res->ai_addr)->sin_port == 0)
            ((struct sockaddr_in *)res->ai_addr)->sin_port = htons(port);
        NSData *address4 = [NSData dataWithBytes:res->ai_addr length:res->ai_addrlen];
        [addresses addObject:address4];
    }
    else if (res->ai_family == AF_INET6)
    {
        // Found IPv6 address.
        // Wrap the native address structure, and add to results.
        
        if (((struct sockaddr_in6 *)res->ai_addr)->sin6_port == 0)
            ((struct sockaddr_in6 *)res->ai_addr)->sin6_port = htons(port);
        NSData *address6 = [NSData dataWithBytes:res->ai_addr length:res->ai_addrlen];
        [addresses addObject:address6];
        
    }
}
至此GCDAsyncSocket.m修改完毕
最后不要忘了加上[asyncSocket setIPv4PreferredOverIPv6:NO];
我的这一句 是在XMPPStream.m的- (BOOL)connectToHost:(NSString *)host onPort:(UInt16)port withTimeout:(NSTimeInterval)timeout error:(NSError **)errPtr;方法里写的。到这修改完毕,快去试试你的IM IPv6吧
最后 iOS的TLS不支持压缩,GCDAsyncSocket内部已经帮我们封装了TLS协商过程。

还有 如果收到报错 KCFStreamErrorDomainSSL Code=-9807 这是因为服务器证书不是正式的证书,所以需要手动认证

我的认证是在XMPPStream的代理方法 
- (void)xmppStream:(XMPPStream *)sender willSecureWithSettings:(NSMutableDictionary *)settings ;里写的

[settings setObject:[NSNumber numberWithBool:YESforKey:(NSString *)kCFStreamPropertySSLPeerTrust];
加上这一句 上面的报错就能解决了










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值