Since IPEndpoint
contains a ToString()
method that outputs:
10.10.10.10:1010
There should also be Parse()
and/or TryParse()
method but there isn't.
I can split the string on the :
and parse an IP address and a port.
But is there a more elegant way?
This is one solution...
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); }
Edit: Added a version that will handle IPv4 and IPv6 the previous one only handles 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); }
I had the requirement of parsing an IPEndpoint with IPv6, v4 and hostnames. The solution I wrote is listed below:
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]; }
This has been tested to work with the following examples:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With