在现代网络环境中,大多数用户通过路由器连接到互联网,这意味着每台机器都被分配了一个私有局域网的内部IP地址,而外部IP地址仅分配给路由器,而不是每台机器。直接找到这个外部地址并不简单,因为这需要处理路由器本身,以及不同的路由器型号等。
最简单的方法是通过向专门提供该地址的网站发送Web请求,例如whatismyipaddress.com、www.whatismyip.com等。在这种情况下,将使用后者。
当然,进行Web请求可能需要时间,特别是如果没有可用的互联网连接,因为默认的超时可能需要几秒钟。这个函数将为完成这项工作,并接受自定义的超时时间:
public static string GetExternalIP(int pTimeOutMiliSeconds)
{
string whatIsMyIp = "http://automation.whatismyip.com/n09230945.asp";
WebClient wc = new WebClient();
UTF8Encoding utf8 = new UTF8Encoding();
try
{
string ipaddr = null;
bool done = false;
wc.DownloadDataCompleted += new DownloadDataCompletedEventHandler((object sender, DownloadDataCompletedEventArgs e) =>
{
ipaddr = utf8.GetString(e.Result);
done = true;
});
wc.DownloadDataAsync(new Uri(whatIsMyIp));
System.DateTime startTime = System.DateTime.Now;
while (!done)
{
System.TimeSpan sp = System.DateTime.Now - startTime;
// We should get a response in less than timeout.
// If not, cancel all and return the internal IP Address
if (sp.TotalMilliseconds > pTimeOutMiliSeconds)
{
done = true;
wc.CancelAsync();
}
}
return ipaddr;
}
catch
{
return null;
}
finally
{
if (wc != null)
{
wc.Dispose();
wc = null;
}
}
}
这段代码的工作原理相当明显。它使用DownloadDataAsync方法,而不是同步的DownloadData,并等待一定的时间。如果在这段时间内没有收到响应,它将取消异步方法并返回null。
在C#中,获取本地主机名和IP地址的方法如下:
string host = System.Net.Dns.GetHostName();
System.Net.IPHostEntry ipEntry = System.Net.Dns.GetHostEntry(host);
System.Net.IPAddress[] addr = ipEntry.AddressList;
for (int i = 0; i < addr.Length; i++)
{
if (addr[i].AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork)
continue;
return addr[i].ToString();
}
return "";