Unity工程建立適配IPv4或者IPv6的通過ip或域名連結的Socket
阿新 • • 發佈:2022-01-29
1.IPv6.m和 IPv6.h 放到 Plugins/IOS下
2.建立Socket,程式碼如下:
1 using UnityEngine; 2 using System; 3 using System.Collections; 4 using System.Net; 5 using System.Net.Sockets; 6 7 enum EAddressFam : byte 8 { 9 IPv4, 10 IPv6 11 } 12 13 /// <summary> 14 /// 建立適配 IPv4 、IPv6 的 Socket15 /// </summary> 16 public class TcpSocket 17 { 18 public Socket Create(string serverAddress, int nPort) 19 { 20 string connectionHost = serverAddress; 21 string convertedHost = string.Empty; 22 AddressFamily convertFamily = AddressFamily.InterNetwork; 23 if(IsIPAddress(serverAddress)) 24 { 25 GetIPType(serverAddress, out convertedHost, out convertFamily); 26 if (string.IsNullOrEmpty(convertedHost)) 27 { 28 connectionHost = convertedHost; 29 } 30 } 31 else 32{ 33 convertedHost = GetIPAddress(serverAddress, EAddressFam.IPv6); 34 if (string.IsNullOrEmpty(convertedHost)) 35 { 36 convertedHost = GetIPAddress(serverAddress, EAddressFam.IPv4); 37 } 38 else 39 { 40 convertFamily = AddressFamily.InterNetworkV6; 41 } 42 43 if (string.IsNullOrEmpty(convertedHost)) 44 { 45 return null; 46 } 47 else 48 { 49 connectionHost = convertedHost; 50 } 51 } 52 53 IPAddress[] ipAddressArray = Dns.GetHostAddresses(connectionHost); 54 if (ipAddressArray.Length <= 0) 55 { 56 return null; 57 } 58 59 IPAddress ipAddress = ipAddressArray[0]; 60 AddressFamily addressFamily = AddressFamily.InterNetwork; 61 if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6) 62 { 63 addressFamily = AddressFamily.InterNetworkV6; 64 } 65 66 Socket socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp) 67 { 68 SendTimeout = 3000, 69 ReceiveTimeout = 3000, 70 SendBufferSize = 64 * 1024, 71 ReceiveBufferSize = 64 * 1024, 72 NoDelay = true 73 }; 74 75 return socket; 76 } 77 78 #region IPv6 79 80 #if (UNITY_IOS || UNITY_IPHONE) && !UNITY_EDITOR 81 private static extern string getIPv6(string host); 82 #endif 83 84 string GetIPv6(string host) 85 { 86 #if (UNITY_IOS || UNITY_IPHONE) && !UNITY_EDITOR 87 return getIPv6(host); 88 #else 89 return host + "&&ipv4"; 90 #endif 91 92 } 93 94 void GetIPType(string serverIp, out string newServerIp, out AddressFamily IPType) 95 { 96 IPType = AddressFamily.InterNetwork; 97 newServerIp = serverIp; 98 try 99 { 100 string ipv6 = GetIPv6(serverIp); 101 if (!string.IsNullOrEmpty(ipv6)) 102 { 103 string[] tmp = System.Text.RegularExpressions.Regex.Split(ipv6, "&&"); 104 if (null != tmp && tmp.Length >= 2) 105 { 106 string type = tmp[1]; 107 if (type == "ipv6") 108 { 109 newServerIp = tmp[0]; 110 IPType = AddressFamily.InterNetworkV6; 111 } 112 } 113 } 114 } 115 catch (Exception) 116 { 117 throw; 118 } 119 } 120 121 string GetIPAddress(string hostName, EAddressFam af) 122 { 123 //基礎作業系統和網路介面卡是否支援 internet 協議的版本 6(ipv6) 124 if (af == EAddressFam.IPv6 && !Socket.OSSupportsIPv6) 125 { 126 return null; 127 } 128 129 if (string.IsNullOrEmpty(hostName)) 130 { 131 return null; 132 } 133 134 string connetIP = string.Empty; 135 IPHostEntry host; 136 137 try 138 { 139 host = Dns.GetHostEntry(hostName); 140 foreach (var ip in host.AddressList) 141 { 142 if (af == EAddressFam.IPv4) 143 { 144 if (ip.AddressFamily == AddressFamily.InterNetwork) 145 { 146 connetIP = ip.ToString(); 147 } 148 } 149 else if (af == EAddressFam.IPv6) 150 { 151 if (ip.AddressFamily == AddressFamily.InterNetworkV6) 152 { 153 connetIP = ip.ToString(); 154 } 155 } 156 } 157 } 158 catch (Exception e) 159 { 160 Debug.LogError("GetIPAddress error : " + e.Message); 161 } 162 163 return connetIP; 164 } 165 166 //判斷str是域名還是ip 167 bool IsIPAddress(string str) 168 { 169 Match match = Regex.Match(str, @"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b"); 170 return match.Success; 171 } 172 173 #endregion 174 }