正如 Paul 所提到的,没有端口号的普通 IP 地址可以通过IPAddress.Parse()
. 但是,如果有端口号和/或主机名(12.34.56.78:90 或 www.example.com:5555),则需要使用不同的方法。如果你想使用 TcpClient 连接,这个函数会这样做:
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);
}
defaultPort
如果输入字符串没有,该参数指定要使用的端口。例如:
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);
}
要在不连接地址的情况下解码地址(例如,验证它是否有效,或者因为您通过需要 IP 地址的 API 进行连接),此方法将这样做(并可选择执行 DNS 查找):
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;
}
奇怪的是,Dns.GetHostAddresses
可以返回多个地址。我问了一下,显然可以简单地使用第一个地址。
如果存在语法错误或解析域名 (FormatException
或SocketException
) 的问题,将引发异常。如果用户指定了域名但是resolveDns==false
,这个方法返回null
。