SessionAddress.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. using System;
  2. using System.Net;
  3. using System.Net.Sockets;
  4. using System.Threading.Tasks;
  5. namespace XGame.Framework.Network
  6. {
  7. /// <summary>
  8. /// 域名解析
  9. /// </summary>
  10. public class SessionAddress
  11. {
  12. private enum InputType
  13. {
  14. Unknown,
  15. Domain,
  16. IPV4,
  17. IPV6
  18. }
  19. private InputType _type = InputType.Unknown;
  20. public string IP { get; private set; }
  21. public int PORT { get; private set; }
  22. public string URI { get; private set; }
  23. public bool IsIpv6
  24. {
  25. get { return _type == InputType.IPV6; }
  26. }
  27. /// <summary>
  28. /// 域名或者IP
  29. /// </summary>
  30. public string Domain { get; private set; }
  31. public ProtocolType ProtocolType { get; private set; }
  32. private const int TimeOut = 4000;
  33. public SessionAddress(AddressInfo info)
  34. {
  35. Domain = info.Address;
  36. PORT = info.Port;
  37. ProtocolType = info.ProtocolType;
  38. URI = info.Uri;
  39. _type = InputType.Domain;
  40. //尝试转换IP地址
  41. //IPAddress.TryParse内部会取传入的值转成整数,然后转成ip地址
  42. //这样传入8,解析出来的就是0.0.0.8
  43. if (IPAddress.TryParse(Domain, out IPAddress address))
  44. {
  45. switch (address.AddressFamily)
  46. {
  47. case AddressFamily.InterNetwork:
  48. {
  49. _type = InputType.IPV4;
  50. IP = Domain;
  51. }
  52. break;
  53. case AddressFamily.InterNetworkV6:
  54. {
  55. _type = InputType.IPV6;
  56. IP = Domain;
  57. }
  58. break;
  59. }
  60. }
  61. }
  62. /// <summary>
  63. /// 异步解析,如果构造的是域名,必须先调用此方法进行解析
  64. /// 若忘记调用此方法进行解析,会导致不可预期的错误
  65. /// callback 解析完毕回调,切记此处回调是线程!!
  66. /// </summary>
  67. public void ParseDnsAsync(Action<SessionAddress> callback)
  68. {
  69. if (_type == InputType.Domain && string.IsNullOrEmpty(IP))
  70. {
  71. Task.Factory.StartNew(() =>
  72. {
  73. try
  74. {
  75. var task = Dns.GetHostEntryAsync(Domain);
  76. if (!task.Wait(TimeOut))
  77. {
  78. Log.Warn($"[Net] Address parse timeout. Domain:{Domain}");
  79. callback?.Invoke(this);
  80. }
  81. else
  82. {
  83. var ipHostEntry = task.Result;
  84. if (ipHostEntry.AddressList.Length > 0)
  85. {
  86. IPAddress address = ipHostEntry.AddressList[0];
  87. if (address.AddressFamily == AddressFamily.InterNetwork)
  88. {
  89. _type = InputType.IPV4;
  90. IP = address.ToString();
  91. }
  92. else if (address.AddressFamily == AddressFamily.InterNetworkV6)
  93. {
  94. _type = InputType.IPV6;
  95. IP = address.ToString();
  96. }
  97. else
  98. {
  99. Log.Warn($"[Net] Address family error. Domain:{Domain} Family:{address.AddressFamily}");
  100. }
  101. }
  102. else
  103. {
  104. Log.Warn($"[Net] No Address. Domain:{Domain}");
  105. }
  106. callback?.Invoke(this);
  107. }
  108. }
  109. catch (Exception e)
  110. {
  111. Log.Exception($"[Net] Address parse error. Domain:{Domain}", e);
  112. callback?.Invoke(this);
  113. }
  114. });
  115. }
  116. else
  117. {
  118. callback?.Invoke(this);
  119. }
  120. }
  121. }
  122. }