最近发现应用出现在IPv6网络环境下XMPP无法登录的情况,查询了网络资料上,发现提供的修改CocoaAsyncSocket源码的方法不起作用,参考资料http://blog.csdn.net/xuxue1072/article/details/51481102,后面通过多方查询与试验,发现只需将cocoaAsynocSocket更新到最新,里面提供了支持IPv6的方法,问题顺利解决,写此文章,以供谨记。
网络上还提供了一些更详细的修改方法,列在这供大家参考,文章链接:http://blog.csdn.net/u011604049/article/details/52288105
- {
- if (res->ai_family == AF_INET)
- {
-
-
-
- NSData *address4 = [NSData dataWithBytes:res->ai_addr length:res->ai_addrlen];
- [addresses addObject:address4];
- }
- else if (res->ai_family == AF_INET6)
- {
-
-
-
-
-
-
- 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)
- {
-
-
-
- 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)
- {
-
-
-
- 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:YES] forKey:(NSString *)kCFStreamPropertySSLPeerTrust];
加上这一句 上面的报错就能解决了