Unity ipv6 Socket

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());
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值