iOS中关于苹果审核IPv6的问题( 四 )


4.5 ping方案支持IPV6
Apple的官方提供了最新的支持IPV6的ping方案,参考地址如下:
只是需要注意的是:
(1)返回的去掉了部分,IPV6的部分也不返回TTL(Time to Live)字段;
(2)IPV6的ICMP报文不进行的处理;
4.6 方案支持IPV6
其实是通过创建套接字模拟ICMP报文的发送,以计算耗时;
两个关键的地方需要注意:
(1)IPV6中去掉字段,改用跳数来表示;
(2)方法可以兼容支持IPV4和IPV6,但是需要最后一个参数,制定目标IP地址的大小;因为前一个参数只是指明了IP地址的开始地址 。千万不要用统一的( ), 因为 和 都是16个字节,两者可以通用,但是的数据结构是28个字节,如果不显式指定,方法就会一直返回-1,报22的错误 。
关键代码如下:(完整代码参考开源组件)
//构造通用的IP地址结构stuck sockaddrNSString *ipAddr0 = [serverDNSs objectAtIndex:0];//设置server主机的套接口地址NSData *addrData = http://www.kingceram.com/post/nil;BOOL isIPV6 = NO;if ([ipAddr0 rangeOfString:@":"].location == NSNotFound) {isIPV6 = NO;struct sockaddr_in nativeAddr4;memset(&nativeAddr4, 0, sizeof(nativeAddr4));nativeAddr4.sin_len = sizeof(nativeAddr4);nativeAddr4.sin_family = AF_INET;nativeAddr4.sin_port = htons(udpPort);inet_pton(AF_INET, ipAddr0.UTF8String, &nativeAddr4.sin_addr.s_addr);addrData = http://www.kingceram.com/post/[NSData dataWithBytes:&nativeAddr4 length:sizeof(nativeAddr4)];} else {isIPV6 = YES;struct sockaddr_in6 nativeAddr6;memset(&nativeAddr6, 0, sizeof(nativeAddr6));nativeAddr6.sin6_len = sizeof(nativeAddr6);nativeAddr6.sin6_family = AF_INET6;nativeAddr6.sin6_port = htons(udpPort);inet_pton(AF_INET6, ipAddr0.UTF8String, &nativeAddr6.sin6_addr);addrData = [NSData dataWithBytes:&nativeAddr6 length:sizeof(nativeAddr6)];}struct sockaddr *destination;destination = (struct sockaddr *)[addrData bytes];//创建socketif ((recv_sock = socket(destination->sa_family, SOCK_DGRAM, isIPV6?IPPROTO_ICMPV6:IPPROTO_ICMP)) < 0)if ((send_sock = socket(destination->sa_family, SOCK_DGRAM, 0)) < 0)//设置sender 套接字的ttlif ((isIPV6? setsockopt(send_sock,IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)):setsockopt(send_sock, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl))) < 0)//发送成功返回值等于发送消息的长度ssize_t sentLen = sendto(send_sock, cmsg, sizeof(cmsg), 0, (struct sockaddr *)destination, isIPV6?sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in));
【iOS中关于苹果审核IPv6的问题】参考: