using System; using System.Linq; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; namespace Grpc.Extension.Common { /// /// NetHelper /// public static class NetHelper { /// /// The ip segment regex /// private const string IPSegmentRegex = @"\d{0,3}"; /// /// Gets the ip. /// /// ip段 /// public static string GetIp(string ipSegment) { if (string.IsNullOrWhiteSpace(ipSegment)) throw new ArgumentNullException(nameof(ipSegment)); //如果设置的IP支持* 的时候,再去智能的选择ip if (!ipSegment.Contains("*")) { return ipSegment; } ipSegment = ipSegment.Replace("*", IPSegmentRegex).Replace(".", "\\."); var hostAddrs = NetworkInterface.GetAllNetworkInterfaces() .Where(i => i.NetworkInterfaceType == NetworkInterfaceType.Ethernet) .SelectMany(i => i.GetIPProperties().UnicastAddresses) .Select(a => a.Address) .Where(a => !(a.IsIPv6LinkLocal || a.IsIPv6Multicast || a.IsIPv6SiteLocal || a.IsIPv6Teredo)) .ToList(); foreach (var ip in hostAddrs) { if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && System.Text.RegularExpressions.Regex.IsMatch(ip.ToString(), ipSegment)) { return ip.ToString(); } } throw new Exception($"找不到ipsegement:{ipSegment}匹配的ip, OR No network adapters with an IPv4 address in the system!"); } /// /// 解析ip和port /// /// /// public static Tuple GetIPAndPort(string serviceAddress) { //解析ip var ipPort = serviceAddress.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries); var ip = NetHelper.GetIp(ipPort[0]); //解析port var port = 0; if (ipPort.Length == 2) int.TryParse(ipPort[1], out port); //随机端口 if (port == 0) port = GetAvailablePort(); return Tuple.Create(ip, port); } /// /// 获取本地ip /// /// public static string GetLocalIp() { string localIP; using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0)) { socket.Connect("8.8.8.8", 65530); IPEndPoint endPoint = socket.LocalEndPoint as IPEndPoint; localIP = endPoint.Address.ToString(); } return localIP; } /// /// 获取可用端口 /// /// public static int GetAvailablePort() { TcpListener l = new TcpListener(IPAddress.Loopback, 0); l.Start(); int port = ((IPEndPoint)l.LocalEndpoint).Port; l.Stop(); return port; } } }