β

苹果ios应用的网络ipv6适配攻略

C++博客-首页原创精华区 1201 阅读

苹果要求在2016年6月1日后新的app必须支持ipv6网络, 技术发展靠苹果果然没错, 但开发者还是要开始忙起来了
这里介绍下Unity3D的适配的一些经验

基本注意点

测试网络环境搭建

转载请注明: http://www.cppblog.com/sunicdavy 战魂小筑

网上有很多翻译了苹果官方的搭建ipv6测试网络环境的文章, 例如:
http://www.cocoachina.com/ios/20160525/16431.html
注意以下几点

转载请注明: http://www.cppblog.com/sunicdavy 战魂小筑

Unity3D的Socket适配

WWW类本身已经支持了IPV6, 无需处理, 这里讲解使用C#原生Socket的处理

P.S. copyStr这种用法参考了 http://www.codeinsect.net/blog/2016/05/26/unity-ipv6-socket-%E6%94%AF%E6%8C%81%EF%BC%8C%E5%B7%B2%E6%B5%8B%E8%AF%95%E9%80%9A%E8%BF%87/
会造成内存泄露, 如果有更好的方法欢迎反馈

转载请注明: http://www.cppblog.com/sunicdavy 战魂小筑

iosaddrinfo.mm

:  #include <sys/socket.h>
:  #include <netdb.h>
:  #include <arpa/inet.h>
:  #include <err.h>
:  #define OUTSTR_SIZE 4096
:  extern "C"
:  {
:      const char* copyStr( const char* str )
:      {
:          char* s = (char*)malloc(strlen(str) + 1);
:          strcpy(s, str);
:          return s;
:      }
:      const char* IOSGetAddressInfo(const char *host )
:      {
:          if( NULL == host )
:              return copyStr("ERROR_HOSTNULL");
:          char outstr[OUTSTR_SIZE];
:          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;
:          printf("getaddrinfo: %s\n", host);
:          int error = getaddrinfo(host, "http", &hints, &res0);
:          if (error != 0 )
:          {
:              printf("getaddrinfo: %s\n", gai_strerror(error));
:              return copyStr("ERROR_GETADDR");
:          }
:          memset( outstr, 0, sizeof(char)*OUTSTR_SIZE );
:          struct sockaddr_in6* addr6;
:          struct sockaddr_in* addr;
:          const char* solvedaddr;
:          char ipbuf[32];
:          for (res = res0; res; res = res->ai_next)
:          {
:              if (res->ai_family == AF_INET6)
:              {
:                  addr6 =( struct sockaddr_in6*)res->ai_addr;
:                  solvedaddr = inet_ntop(AF_INET6, &addr6->sin6_addr, ipbuf, sizeof(ipbuf));
:                  strcat ( outstr, "ipv6|");
:                  strcat ( outstr, solvedaddr);
:              }
:              else
:              {
:                  addr =( struct sockaddr_in*)res->ai_addr;
:                  solvedaddr = inet_ntop(AF_INET, &addr->sin_addr, ipbuf, sizeof(ipbuf));
:                  strcat ( outstr, "ipv4|");
:                  strcat ( outstr, solvedaddr);
:              }
:              strcat ( outstr, "|");
:          }
:          return copyStr(outstr);
:      }
:  }
转载请注明:http://www.cppblog.com/sunicdavy战魂小筑

iosaddrinfo.h

:  #pragma once
:  extern "C"{
:      const char* IOSGetAddressInfo(const char *host );
:  }

:  using System;
:  using System.Net;
:  using System.Net.Sockets;
:  using System.Runtime.InteropServices;
:  using UnityEngine;
:  using System.Collections;
:  using System.Collections.Generic;
:  public class IOSIPV6
:  {
:      [DllImport("__Internal")]
:      private static extern string IOSGetAddressInfo(string host );  
:      public static IPAddress[] ResolveIOSAddress(string host, out AddressFamily af)
:      {
:          af = AddressFamily.InterNetwork;
:          var outstr = IOSGetAddressInfo(host);
:          Debug.Log("IOSGetAddressInfo: " + outstr);
:          if (outstr.StartsWith ("ERROR")) 
:          {
:              return null;
:          }
:          var addressliststr = outstr.Split('|');
:          var addrlist = new List<IPAddress>();
:          foreach (string s in addressliststr)
:          {
:              if (String.IsNullOrEmpty(s.Trim()))
:                  continue;
:              switch( s )
:              {
:                  case "ipv6":
:                      {                        
:                          af = AddressFamily.InterNetworkV6;
:                      }
:                      break;
:                  case "ipv4":
:                      {
:                          af = AddressFamily.InterNetwork;
:                      }
:                      break;
:                  default:
:                      {
:                          addrlist.Add(IPAddress.Parse(s));
:                      }
:                      break;
:              }
:          }
:          return addrlist.ToArray();
:      }
:  }
转载请注明:http://www.cppblog.com/sunicdavy战魂小筑

参考链接

官方文档
https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/UnderstandingandPreparingfortheIPv6Transition/UnderstandingandPreparingfortheIPv6Transition.html#//apple_ref/doc/uid/TP40010220-CH213-SW1

某人的解决方案
http://www.codeinsect.net/blog/2016/05/26/unity-ipv6-socket-%E6%94%AF%E6%8C%81%EF%BC%8C%E5%B7%B2%E6%B5%8B%E8%AF%95%E9%80%9A%E8%BF%87/
注意, 此方案中的方法可用, 但是地址并不能解决南北互通的问题

战魂小筑 2016-06-16 14:18 发表评论

作者:C++博客-首页原创精华区
专注于C++技术
原文地址:苹果ios应用的网络ipv6适配攻略, 感谢原作者分享。

发表评论