由于IPEndpoint
包含一个ToString()
输出的方法:
10.10.10.10:1010
还应该有Parse()
和/或TryParse()
方法,但没有.
我可以拆分字符串:
并解析IP地址和端口.
但是有更优雅的方式吗?
这是一个解决方案......
public static IPEndPoint CreateIPEndPoint(string endPoint) { string[] ep = endPoint.Split(':'); if(ep.Length != 2) throw new FormatException("Invalid endpoint format"); IPAddress ip; if(!IPAddress.TryParse(ep[0], out ip)) { throw new FormatException("Invalid ip-adress"); } int port; if(!int.TryParse(ep[1], NumberStyles.None, NumberFormatInfo.CurrentInfo, out port)) { throw new FormatException("Invalid port"); } return new IPEndPoint(ip, port); }
编辑:添加了一个处理IPv4和IPv6的版本,前一个版本只处理IPv4.
// Handles IPv4 and IPv6 notation. public static IPEndPoint CreateIPEndPoint(string endPoint) { string[] ep = endPoint.Split(':'); if (ep.Length < 2) throw new FormatException("Invalid endpoint format"); IPAddress ip; if (ep.Length > 2) { if (!IPAddress.TryParse(string.Join(":", ep, 0, ep.Length - 1), out ip)) { throw new FormatException("Invalid ip-adress"); } } else { if (!IPAddress.TryParse(ep[0], out ip)) { throw new FormatException("Invalid ip-adress"); } } int port; if (!int.TryParse(ep[ep.Length - 1], NumberStyles.None, NumberFormatInfo.CurrentInfo, out port)) { throw new FormatException("Invalid port"); } return new IPEndPoint(ip, port); }
我有要求使用IPv6,v4和主机名解析IPEndpoint.我写的解决方案如下:
public static IPEndPoint Parse(string endpointstring) { return Parse(endpointstring, -1); } public static IPEndPoint Parse(string endpointstring, int defaultport) { if (string.IsNullOrEmpty(endpointstring) || endpointstring.Trim().Length == 0) { throw new ArgumentException("Endpoint descriptor may not be empty."); } if (defaultport != -1 && (defaultport < IPEndPoint.MinPort || defaultport > IPEndPoint.MaxPort)) { throw new ArgumentException(string.Format("Invalid default port '{0}'", defaultport)); } string[] values = endpointstring.Split(new char[] { ':' }); IPAddress ipaddy; int port = -1; //check if we have an IPv6 or ports if (values.Length <= 2) // ipv4 or hostname { if (values.Length == 1) //no port is specified, default port = defaultport; else port = getPort(values[1]); //try to use the address as IPv4, otherwise get hostname if (!IPAddress.TryParse(values[0], out ipaddy)) ipaddy = getIPfromHost(values[0]); } else if (values.Length > 2) //ipv6 { //could [a:b:c]:d if (values[0].StartsWith("[") && values[values.Length - 2].EndsWith("]")) { string ipaddressstring = string.Join(":", values.Take(values.Length - 1).ToArray()); ipaddy = IPAddress.Parse(ipaddressstring); port = getPort(values[values.Length - 1]); } else //[a:b:c] or a:b:c { ipaddy = IPAddress.Parse(endpointstring); port = defaultport; } } else { throw new FormatException(string.Format("Invalid endpoint ipaddress '{0}'", endpointstring)); } if (port == -1) throw new ArgumentException(string.Format("No port specified: '{0}'", endpointstring)); return new IPEndPoint(ipaddy, port); } private static int getPort(string p) { int port; if (!int.TryParse(p, out port) || port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort) { throw new FormatException(string.Format("Invalid end point port '{0}'", p)); } return port; } private static IPAddress getIPfromHost(string p) { var hosts = Dns.GetHostAddresses(p); if (hosts == null || hosts.Length == 0) throw new ArgumentException(string.Format("Host not found: {0}", p)); return hosts[0]; }
已经过测试,可以使用以下示例:
0.0.0.0:100
0.0.0.0
[:: 1]:100
[:: 1]
:: 1
[A B C D]
[A:B:C:d]:100
example.org
example.org:100
看起来已经有一个内置的Parse方法来处理ip4和ip6地址 http://msdn.microsoft.com/en-us/library/system.net.ipaddress.parse%28v=vs.110%29.aspx
// serverIP can be in ip4 or ip6 format string serverIP = "192.168.0.1"; string port = 8000; IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(serverIP), port);
这是我将文本解析为的版本IPEndPoint
:
private static IPEndPoint ParseIPEndPoint(string text) { Uri uri; if (Uri.TryCreate(text, UriKind.Absolute, out uri)) return new IPEndPoint(IPAddress.Parse(uri.Host), uri.Port < 0 ? 0 : uri.Port); if (Uri.TryCreate(String.Concat("tcp://", text), UriKind.Absolute, out uri)) return new IPEndPoint(IPAddress.Parse(uri.Host), uri.Port < 0 ? 0 : uri.Port); if (Uri.TryCreate(String.Concat("tcp://", String.Concat("[", text, "]")), UriKind.Absolute, out uri)) return new IPEndPoint(IPAddress.Parse(uri.Host), uri.Port < 0 ? 0 : uri.Port); throw new FormatException("Failed to parse text to IPEndPoint"); }
经过测试:
0.0.0.0
0.0.0.0:100
[:: 1]:100
[:: 1]:0
:: 1
[2001:db8:85a3:8d3:1319:8a2e:370:7348]
[2001:db8:85a3:8d3:1319:8a2e:370:7348]:100
http://0.0.0.0
http://0.0.0.0:100
http:// [:: 1]
http:// [:: 1]:100
https://0.0.0.0
https:// [:: 1]