cocos2dx解決蘋果正版ipv6的問題

蘋果官方出了新的規定,要求新上架的app都必須單獨支持ipv6-only的網絡。html

具體的要求連接:https://developer.apple.com/library/mac/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/UnderstandingandPreparingfortheIPv6Transition/UnderstandingandPreparingfortheIPv6Transition.html#//apple_ref/doc/uid/TP40010220-CH213-SW13服務器

熱心的網友來了箇中文版本的:網絡

http://kepenj.me/2016/05/22/Supporting-IPv6/app

 

全民神魔跟三打白骨精兩個項目用的仍是兩年前的cocos2dx3.0rc版本,明顯各類不支持。並且咱們本身重寫了socket,因此須要修改的地方有下面三個:curl

1.curlsocket

開始的時候,本身上curl上了個最新的源碼,替換掉舊的,結果不行。測試

而後發現原來還有個libcurl.a的庫要替換的。一併替換了,也是不行的。ui

而後就把電腦裏的好幾個版本都拿去替換,仍是不行。url

最後,實在沒辦法,跑去cocos2d-x官網看有沒有相關歷史版本能夠嘗試使用的。結果看到這個:spa

[3.11.1] 支持IPV6-Only網絡
[3.11] Chipmunk升級到v7.0.1
[3.11] JSB使用新的內存模型,在JS腳本不須要關心對象的生命週期,該特性默認關閉
[3.11] CURL升級到v7.48
[3.11] OpenSSL升級到v1.0.2g
[3.11] 可使用VSCode或者新版本的Firefox調試JSB程序
[3.11] 全面升級 WebGL 渲染器

也就是官網特意加多個版本,去解決這個IPV6-Only網絡的問題。

知道這個就好辦了,直接下載最新的引擎。拿裏面的關於curl的庫跟源碼對舊項目進行替換。

a庫那裏有個問題稍微測試下,舊版本的cocos2dx只有libhcurl.a,而新版本的是有libcurl.a, libssl.a, libcrypto.a,三個都要加進去,並且還要加到項目的引用。

 

2.host to ip
域名到ip的轉換。

咱們的服務器是配置了域名,而後把客戶端鏈接的時候,先進行域名到ip的轉換。再用ip去鏈接服務器。

原來咱們用的是 gethostbyname的方法去獲取ipv4的ip。上面發的連接裏有提到這個問題,ipv6要用gethostbyname2。

也是作了嘗試,實在c語言水平有限,並且也不知道怎麼去判斷網絡是ipv4仍是ipv6的問題。

最後找到了另一個域名轉換ip的方法。就是用getaddrinfo,這個方法的好處在於,解決了轉換IP,又解決了判斷網絡。

這個是oc代碼。

- (NSString *) getIPWithHostName:(const NSString *)hostName {
    struct addrinfo * result;
    struct addrinfo * res;
    char ipv4[128];
    char ipv6[128];
    int error;
    BOOL IS_IPV6 = FALSE;
    bzero(&ipv4, sizeof(ipv4));
    bzero(&ipv4, sizeof(ipv6));
    
    error = getaddrinfo([hostName UTF8String], NULL, NULL, &result);
    if(error != 0) {
        NSLog(@"error in getaddrinfo:%d", error);
        return nil;
    }
    for(res = result; res!=NULL; res = res->ai_next) {
        char hostname[1025] = "";
        error = getnameinfo(res->ai_addr, res->ai_addrlen, hostname, 1025, NULL, 0, 0);
        if(error != 0) {
            NSLog(@"error in getnameifno: %s", gai_strerror(error));
            continue;
        }
        else {
            switch (res->ai_addr->sa_family) {
                case AF_INET:
                    memcpy(ipv4, hostname, 128);
                    break;
                case AF_INET6:
                    memcpy(ipv6, hostname, 128);
                    IS_IPV6 = TRUE;
                default:
                    break;
            }
            NSLog(@"hostname: %s ", hostname);
        }
    }
    freeaddrinfo(result);
    if(IS_IPV6 == TRUE) return [NSString stringWithUTF8String:ipv6];
    return [NSString stringWithUTF8String:ipv4];
}

 

3.socket

ipv6裏面,對socket的建立及鏈接都須要有相關的修改。

感謝這位仁兄提供的解決方法。

http://blog.csdn.net/hepeng597/article/details/7803277

照着上面這個連接的對比方法,對socket進行修改便可。

這裏有個小技巧,若是有須要對鏈接地址進行網絡判斷的話,能夠判斷ip地址裏是否有冒號 ":"

c語言裏能夠用這個判斷 strchr(server, ':') != NULL

相關文章
相關標籤/搜索