1. 在OC的.m文件中添加如下方法,用于被Unity调用
IOS_GetIPv6 方法将返回转换好的IP地址,提供unity使用
#import <Foundation/Foundation.h>
#import "UnityToIOS.h"
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import "IOPSKeys.h"
#import "UnityAppController.h"
#import "AppDelegate.h"
#import <sys/socket.h>
#import <netdb.h>
#import <arpa/inet.h>
#import <err.h>
#define MakeStringCopy( _x_ ) ( _x_ != NULL && [_x_ isKindOfClass:[NSString class]] ) ? strdup( [_x_ UTF8String] ) : NULL
#if defined(__cplusplus)
extern "C"{
#endif
const char * IOS_GetIPv6(const char *mHost,const char *mPort)
{
NSLog(@"获取IPv6信息");
if( nil == mHost )
return NULL;
const char *newChar = "No";
struct addrinfo* res0;
struct addrinfo hints;
struct addrinfo* res;
int n, s;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_DEFAULT;
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if((n=getaddrinfo(mHost, "http", &hints, &res0))!=0)
{
printf("getaddrinfo error: %s\n",gai_strerror(n));
return NULL;
}
struct sockaddr_in6* addr6;
struct sockaddr_in* addr;
NSString * NewStr = NULL;
char ipbuf[32];
s = -1;
for(res = res0; res; res = res->ai_next)
{
if (res->ai_family == AF_INET6)
{
addr6 =( struct sockaddr_in6*)res->ai_addr;
newChar = inet_ntop(AF_INET6, &addr6->sin6_addr, ipbuf, sizeof(ipbuf));
NSString * TempA = [[NSString alloc] initWithCString:(const char*)newChar
encoding:NSASCIIStringEncoding];
NSString * TempB = [NSString stringWithUTF8String:"&&ipv6"];
NewStr = [TempA stringByAppendingString: TempB];
printf("%s\n", newChar);
}
else
{
addr =( struct sockaddr_in*)res->ai_addr;
newChar = inet_ntop(AF_INET, &addr->sin_addr, ipbuf, sizeof(ipbuf));
NSString * TempA = [[NSString alloc] initWithCString:(const char*)newChar
encoding:NSASCIIStringEncoding];
NSString * TempB = [NSString stringWithUTF8String:"&&ipv4"];
NewStr = [TempA stringByAppendingString: TempB];
printf("%s\n", newChar);
}
break;
}
freeaddrinfo(res0);
printf("getaddrinfo OK");
NSString * mIPaddr = NewStr;
return MakeStringCopy(mIPaddr);
}
#if defined(__cplusplus)
}
#endif
Unity中调用OC的方法
[DllImport("__Internal")]
static extern string IOS_GetIPv6 (string host, string port);
将通过OC底层转换过以后的IP地址,拼接上IPv4 或 IPv6 的区别,返回调用者
public override string GetIpv6 (string host, string port)
{
#if UNITY_IPHONE && !UNITY_EDITOR
{
string ipv6str = IOS_GetIPv6(host,port);
Debug.Log("____________________ipv6:"+ipv6str);
return ipv6str;
}
#else
return host+"&&ipv4";
#endif
}
在Socket连接的地方,设置如下代码,用于将IPv4 地址转换为 IPv6
/// <summary>
/// 获取IP类型
/// </summary>
/// <param name="serverIp">Server ip.</param>
/// <param name="serverPorts">Server ports.</param>
/// <param name="newServerIp">New server ip.</param>
/// <param name="mIPType">M IP type.</param>
void getIPType(string serverIp, string serverPorts, out string newServerIp, out AddressFamily mIPType)
{
mIPType = AddressFamily.InterNetwork;
newServerIp = serverIp;
try
{
string mIpv6 = GamePlatformAppliction.GetInstance().GetIpv6(serverIp, serverPorts);
if (!string.IsNullOrEmpty(mIpv6))
{
string[] m_StrTemp = System.Text.RegularExpressions.Regex.Split(mIpv6, "&&");
if (m_StrTemp != null && m_StrTemp.Length >= 2)
{
string IPType = m_StrTemp[1];
if (IPType == "ipv6")
{
newServerIp = m_StrTemp[0];
mIPType = AddressFamily.InterNetworkV6;
}
}
}
}
catch (Exception e)
{
Debug.LogError("ipv6: " + e.Message);
}
}
/// <summary>
/// 苹果设备上,将IP转化为IPv6
/// </summary>
/// <param name="ip"></param>
/// <param name="port"></param>
/// <returns></returns>
EndPoint ConverIP(string ip,int port)
{
string newServerIP = "";
AddressFamily addressFamily = AddressFamily.InterNetwork;
#if UNITY_IPHONE && !UNITY_EDITOR
getIPType(ip, port.ToString(), out newServerIP, out addressFamily);
if (!string.IsNullOrEmpty(newServerIP))
{
ip = newServerIP;
}
#endif
socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipaddress = IPAddress.Parse(ip);
point = new IPEndPoint(ipaddress, port);
return point;
}
初始化Scoket连接需要的参数,IP和端口号
public ConnectServer(string ip, int port)
{
//创建客户端连接对象
ConverIP(ip,port);
}
public void OnClickConnect()
{
try
{
//异步连接到服务器
socket.BeginConnect(point, new AsyncCallback(ConnectCallback), defaultPort);
}
catch (Exception ex)
{
Debug.Log(ex.ToString());
}
}