NetEndPoint.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. #if DEBUG && !UNITY_WP_8_1 && !UNITY_WSA_8_1
  2. #if !WINRT || UNITY_EDITOR
  3. using System;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. namespace FlyingWormConsole3.LiteNetLib
  7. {
  8. public sealed class NetEndPoint
  9. {
  10. public string Host { get { return EndPoint.Address.ToString(); } }
  11. public int Port { get { return EndPoint.Port; } }
  12. internal readonly IPEndPoint EndPoint;
  13. internal NetEndPoint(IPEndPoint ipEndPoint)
  14. {
  15. EndPoint = ipEndPoint;
  16. }
  17. public override bool Equals(object obj)
  18. {
  19. if (!(obj is NetEndPoint))
  20. {
  21. return false;
  22. }
  23. return EndPoint.Equals(((NetEndPoint)obj).EndPoint);
  24. }
  25. public override string ToString()
  26. {
  27. return EndPoint.ToString();
  28. }
  29. public override int GetHashCode()
  30. {
  31. return EndPoint.GetHashCode();
  32. }
  33. public NetEndPoint(string hostStr, int port)
  34. {
  35. IPAddress ipAddress;
  36. if (!IPAddress.TryParse(hostStr, out ipAddress))
  37. {
  38. if (Socket.OSSupportsIPv6)
  39. {
  40. if (hostStr == "localhost")
  41. {
  42. ipAddress = IPAddress.IPv6Loopback;
  43. }
  44. else
  45. {
  46. ipAddress = ResolveAddress(hostStr, AddressFamily.InterNetworkV6);
  47. }
  48. }
  49. if (ipAddress == null)
  50. {
  51. ipAddress = ResolveAddress(hostStr, AddressFamily.InterNetwork);
  52. }
  53. }
  54. if (ipAddress == null)
  55. {
  56. throw new Exception("Invalid address: " + hostStr);
  57. }
  58. EndPoint = new IPEndPoint(ipAddress, port);
  59. }
  60. private IPAddress ResolveAddress(string hostStr, AddressFamily addressFamily)
  61. {
  62. #if NETCORE
  63. var hostTask = Dns.GetHostEntryAsync(hostStr);
  64. hostTask.Wait();
  65. var host = hostTask.Result;
  66. #else
  67. var host = Dns.GetHostEntry(hostStr);
  68. #endif
  69. foreach (IPAddress ip in host.AddressList)
  70. {
  71. if (ip.AddressFamily == addressFamily)
  72. {
  73. return ip;
  74. }
  75. }
  76. return null;
  77. }
  78. internal long GetId()
  79. {
  80. byte[] addr = EndPoint.Address.GetAddressBytes();
  81. long id = 0;
  82. if (addr.Length == 4) //IPv4
  83. {
  84. id = addr[0];
  85. id |= (long)addr[1] << 8;
  86. id |= (long)addr[2] << 16;
  87. id |= (long)addr[3] << 24;
  88. id |= (long)EndPoint.Port << 32;
  89. }
  90. else if (addr.Length == 16) //IPv6
  91. {
  92. id = addr[0] ^ addr[8];
  93. id |= (long)(addr[1] ^ addr[9]) << 8;
  94. id |= (long)(addr[2] ^ addr[10]) << 16;
  95. id |= (long)(addr[3] ^ addr[11]) << 24;
  96. id |= (long)(addr[4] ^ addr[12]) << 32;
  97. id |= (long)(addr[5] ^ addr[13]) << 40;
  98. id |= (long)(addr[6] ^ addr[14]) << 48;
  99. id |= (long)(Port ^ addr[7] ^ addr[15]) << 56;
  100. }
  101. return id;
  102. }
  103. }
  104. }
  105. #else
  106. using System;
  107. using Windows.Networking;
  108. using Windows.Networking.Sockets;
  109. namespace FlyingWormConsole3.LiteNetLib
  110. {
  111. public sealed class NetEndPoint
  112. {
  113. public string Host { get { return HostName.DisplayName; } }
  114. public int Port { get; private set; }
  115. internal readonly HostName HostName;
  116. internal readonly string PortStr;
  117. internal NetEndPoint(int port)
  118. {
  119. HostName = null;
  120. PortStr = port.ToString();
  121. Port = port;
  122. }
  123. public override bool Equals(object obj)
  124. {
  125. if (!(obj is NetEndPoint))
  126. {
  127. return false;
  128. }
  129. NetEndPoint other = (NetEndPoint) obj;
  130. return HostName.IsEqual(other.HostName) && PortStr.Equals(other.PortStr);
  131. }
  132. public override int GetHashCode()
  133. {
  134. return HostName.CanonicalName.GetHashCode() ^ PortStr.GetHashCode();
  135. }
  136. internal long GetId()
  137. {
  138. //Check locals
  139. if (HostName == null)
  140. {
  141. return ParseIpToId("0.0.0.0");
  142. }
  143. if (HostName.DisplayName == "localhost")
  144. {
  145. return ParseIpToId("127.0.0.1");
  146. }
  147. //Check remote
  148. string hostIp = string.Empty;
  149. var task = DatagramSocket.GetEndpointPairsAsync(HostName, "0").AsTask();
  150. task.Wait();
  151. //IPv4
  152. foreach (var endpointPair in task.Result)
  153. {
  154. hostIp = endpointPair.RemoteHostName.CanonicalName;
  155. if (endpointPair.RemoteHostName.Type == HostNameType.Ipv4)
  156. {
  157. return ParseIpToId(hostIp);
  158. }
  159. }
  160. //Else
  161. return hostIp.GetHashCode() ^ Port;
  162. }
  163. private long ParseIpToId(string hostIp)
  164. {
  165. long id = 0;
  166. string[] ip = hostIp.Split('.');
  167. id |= long.Parse(ip[0]);
  168. id |= long.Parse(ip[1]) << 8;
  169. id |= long.Parse(ip[2]) << 16;
  170. id |= long.Parse(ip[3]) << 24;
  171. id |= (long)Port << 32;
  172. return id;
  173. }
  174. public override string ToString()
  175. {
  176. return HostName.CanonicalName + ":" + PortStr;
  177. }
  178. public NetEndPoint(string hostName, int port)
  179. {
  180. var task = DatagramSocket.GetEndpointPairsAsync(new HostName(hostName), port.ToString()).AsTask();
  181. task.Wait();
  182. HostName = task.Result[0].RemoteHostName;
  183. Port = port;
  184. PortStr = port.ToString();
  185. }
  186. internal NetEndPoint(HostName hostName, string port)
  187. {
  188. HostName = hostName;
  189. Port = int.Parse(port);
  190. PortStr = port;
  191. }
  192. }
  193. }
  194. #endif
  195. #endif