appstore审核的那些事 --2. IPv6环境下的支持

来源:互联网 发布:mac桌面不见 编辑:程序博客网 时间:2024/06/08 08:02

AppStore审核的时候反馈:

We discovered one or more bugs in your app when reviewed on iPad and iPhone running iOS 10.2 on Wi-Fi connected to an IPv6 network.


因此我需要修改IPv6环境下的支持。使用了socket的时候仅支持了IPv4

1.在网络连通性检测的时候使用了socket

原来的表现:在IPv6环境下显示网络连接不通,包括直接IP访问(192.168.1.22)和域名访问(baidu.com

修改后结果:IP访问和域名访问都显示可以成功访问(都可以直接获取的IPv6格式的地址)

原理不再赘述,详见最下面的链接

主要修改的是:

1 gethostbyname —> getaddrinfo

2)根据getaddrinfoIPv4IPv6的区分

3)添加sockaddr_in6IPv6相关内容

修改后代码:

/** @brief     测试连接 */+ (void)testConnection:(NSString*)host port:(NSNumber*)port compelete:(nullable void(^)(BOOL isSuccess))compelete {    if(!host){        compelete(NO);    }    NSOperationQueue *operationQueue  = [[NSOperationQueue alloc]init];    [operationQueue addOperationWithBlock:^{        //    NSString * host =@"123.33.33.1";        //    NSNumber * port = @1233;                // 创建 socket        int socketFileDescriptor = socket(AF_INET, SOCK_STREAM, 0);        if (-1 == socketFileDescriptor) {            NSLogD(@"创建失败");            [[NSOperationQueue mainQueue]addOperationWithBlock:^{                compelete(NO);            }];            return;        }        NSLogD(@"host   %@:%@",host,port);                // 获取 IP 地址        int error, sockfd;        const char *cause = NULL;        struct addrinfo hints, *res, *res0;        memset(&hints, 0, sizeof(hints));        hints.ai_family = PF_UNSPEC;        hints.ai_socktype = SOCK_STREAM;        hints.ai_flags = AI_DEFAULT;        error = getaddrinfo([host UTF8String], "http", &hints, &res0);        NSLogD(@"getaddrinfo    %d",error);                if (0 != error) {            close(socketFileDescriptor);            NSLogD(@"%@",@"无法解析服务器的主机名");            [[NSOperationQueue mainQueue]addOperationWithBlock:^{                compelete(NO);            }];            return;        }        sockfd = -1;        struct sockaddr_in *addr;        struct sockaddr_in6 *addr6;        char ipbuf[28];        for (res = res0; res; res = res->ai_next) {            sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);            if (sockfd < 0) {                cause = "socket";                continue;            }            if(AF_INET6==res->ai_family){                addr6 = (struct sockaddr_in6 *)res->ai_addr;                addr6->sin6_port = htons([port intValue]);  // 修改端口号                printf("%s\n", inet_ntop(AF_INET6,  &addr6->sin6_addr, ipbuf, 28));                // 连接 socket                if (connect(sockfd, (struct sockaddr *) addr6, sizeof(*addr6)) < 0) {                    cause = "connect v6";                    close(sockfd);                    sockfd = -1;                    continue;                }            }else{                addr = (struct sockaddr_in *)res->ai_addr;                addr->sin_port = htons([port intValue]);                printf("%s\n", inet_ntop(AF_INET,  &addr->sin_addr, ipbuf, 16));                //            // 设置为非阻塞                //            fcntl(sockfd,F_SETFL,fcntl(sockfd,F_GETFL,0)|O_NONBLOCK);                // 连接 socket                if (connect(sockfd, (struct sockaddr *) addr, sizeof(*addr)) < 0) {                    //                if (connect(sockfd, res->ai_addr, res->ai_addrlen) < 0) {                    cause = "connect";                    close(sockfd);                    sockfd = -1;                    continue;                }            }            break;  /* okay we got one */        }        if (sockfd < 0) {            /*NOTREACHED*/            NSLog(@"error cause    %s", cause);            [[NSOperationQueue mainQueue]addOperationWithBlock:^{                compelete(NO);            }];            return;        }        NSLogD(@"连接成功%@",host);        close(sockfd);        [[NSOperationQueue mainQueue]addOperationWithBlock:^{            compelete(YES);        }];            }];}

调用访问网络的方法:

[Utils testConnection:service port:@(port) compelete:^(BOOL isSuccess) {    if(isSuccess){        // success    }else{        // failure    }}];


2.在访问服务端接口的时候用了socket

与上述方法相同,只不过根据需求设置成阻塞/非阻塞的,看最后是否需要调用close(sockfd);关闭此连接


PS. 

1.IPv6环境的搭建

1)用wifi:http://www.jianshu.com/p/632d995749e1

2)用4G:http://www.cnblogs.com/SUPER-F/p/IPV6.html

2.官方指导和使用

https://developer.apple.com/library/content/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/UnderstandingandPreparingfortheIPv6Transition/UnderstandingandPreparingfortheIPv6Transition.html#//apple_ref/doc/uid/TP40010220-CH213-SW11

3.讲的比较详细的socket使用:https://github.com/WeMobileDev/article/blob/master/IPv6%20socket%E7%BC%96%E7%A8%8B.md#%E6%B7%B7%E5%90%88%E7%9A%84%E6%96%B9%E6%A1%88mac-osioslinuxandroid%E9%83%BD%E6%94%AF%E6%8C%81windowswp%E5%BE%85%E6%B5%8B%E8%AF%95


0 0
原创粉丝点击