As Paul mentioned, a plain IP Address with no port number can be parsed by IPAddress.Parse()
. However, if there is a port number and/or hostname (12.34.56.78:90 or www.example.com:5555), a different approach is needed. If you want to use TcpClient to connect, this function will do so:
public static TcpClient Connect(string ipAndPort, int defaultPort)
{
if (ipAndPort.Contains("/"))
throw new FormatException("Input should only be an IP address and port");
// Uri requires a prefix such as "http://", "ftp://" or even "foo://".
// Oddly, Uri accepts the prefix "//" UNLESS there is a port number.
Uri uri = new Uri("tcp://" + ipAndPort);
string ipOrDomain = uri.Host;
int port = uri.Port != -1 ? uri.Port : defaultPort;
return new TcpClient(ipOrDomain, port);
}
The defaultPort
parameter specifies the port to use if the input string doesn't have one. For example:
using (NetworkStream s = Connect("google.com", 80).GetStream())
{
byte[] line = Encoding.UTF8.GetBytes("GET / HTTP/1.0\r\n\r\n");
s.Write(line, 0, line.Length);
int b;
while ((b = s.ReadByte()) != -1)
Console.Write((char)b);
}
To decode the address without connecting to it (e.g. to verify that it is valid, or because you are connecting via an API that requires an IP address), this method will do so (and optionally perform DNS lookup):
public static IPAddress Resolve(string ipAndPort, ref int port, bool resolveDns)
{
if (ipAndPort.Contains("/"))
throw new FormatException("Input address should only contain an IP address and port");
Uri uri = new Uri("tcp://" + ipAndPort);
if (uri.Port != -1)
port = uri.Port;
if (uri.HostNameType == UriHostNameType.IPv4 || uri.HostNameType == UriHostNameType.IPv6)
return IPAddress.Parse(uri.Host);
else if (resolveDns)
return Dns.GetHostAddresses(uri.Host)[0];
else
return null;
}
Curiously, Dns.GetHostAddresses
can return multiple addresses. I asked about it, and apparently it's okay to simply take the first address.
An exception will be raised if there is a syntax error or a problem resolving the domain name (FormatException
or SocketException
). If the user specified a domain name but resolveDns==false
, this method returns null
.