获取公共互联网IP地址/地理位置的聪明方法

3

7
如何在不依赖公共服务器的情况下获取您的外部IP地址?为什么?您应该意识到,您的“外部”IP地址在某种程度上始终依赖于公共互联网。 - bzlm
可能会有所帮助:http://msdn.microsoft.com/zh-cn/library/system.net.webrequest.getsystemwebproxy.aspx - CodingBarfield
2
最简单的“作弊”方法:使用WebClient打开http://www.whatismyip.com/并解析输出以获取您的IP地址。 - BrokenGlass
我移除了不使用外部服务器的要求,以免受到攻击。 - Daniel Mošmondor
whatismyip.com网站有一个自动化页面,供脚本和程序使用,只返回IP地址,因此您无需屏幕抓取。该URL链接在此处:http://www.whatismyip.com/automation/ - indiv
可能是如何在C#中获取自己的IP地址?的重复问题。 - Oleg V. Volkov
9个回答

24

我更喜欢http://icanhazip.com。它返回一个简单的文本字符串,无需进行HTML解析。

string myIp = new WebClient().DownloadString(@"http://icanhazip.com").Trim();

你能否更详细地描述一下在代码后台中如何使用它? - saeed

6

经过一些搜索并扩大我的要求,我发现这不仅可以获取IP地址,还可以获取地理位置信息:

class GeoIp
{
    static public GeoIpData GetMy()
    {
        string url = "http://freegeoip.net/xml/";
        WebClient wc = new WebClient();
        wc.Proxy = null;
        MemoryStream ms = new MemoryStream(wc.DownloadData(url));
        XmlTextReader rdr = new XmlTextReader(url);
        XmlDocument doc = new XmlDocument();
        ms.Position = 0;
        doc.Load(ms);
        ms.Dispose();
        GeoIpData retval = new GeoIpData();
        foreach (XmlElement el in doc.ChildNodes[1].ChildNodes)
        {
            retval.KeyValue.Add(el.Name, el.InnerText);
        }
        return retval;
    }
}

返回了XML,因此键/值字典将填充如下:

<Response>
    <Ip>93.139.127.187</Ip>
    <CountryCode>HR</CountryCode>
    <CountryName>Croatia</CountryName>
    <RegionCode>16</RegionCode>
    <RegionName>Varazdinska</RegionName>
    <City>Varazdinske Toplice</City>
    <ZipCode/>
    <Latitude>46.2092</Latitude>
    <Longitude>16.4192</Longitude>
    <MetroCode/>
</Response>

为了方便起见,返回类:
class GeoIpData
{
    public GeoIpData()
    {
        KeyValue = new Dictionary<string, string>();
    }
    public Dictionary<string, string> KeyValue;
}

5

问题在于你要查找的IP地址并不属于你的计算机,而是属于你的NAT路由器。我能想到的获取它的唯一方法是使用外部服务器或查询路由器。

如果你的路由器支持SNMP,也许可以通过这种方式获取它。


2

我相信你需要连接到某个服务器才能获取你的外部IP。


2
根据您使用的路由器不同,很可能可以直接从路由器获取外部IP地址。大多数路由器都有一个网页界面,所以只需导航到正确的网页(例如,“192.168.0.1/whatever”)并从该页面“抓取”外部IP地址即可。然而,这种方法存在问题,因为它十分脆弱 -- 如果您更改(甚至重新配置)路由器,很可能会导致无法获取IP地址。

2

如果uPNP失败了,您可以尝试使用whatsmyip.com。


uPNP听起来很有前途,但使用什么库?C#? - Daniel Mošmondor

0
如果您担心连接中断或网站的可用性,您也可以尝试通过包含上述建议来避免这个问题。
    using System.Threading;

    Task<string>[] tasks = new[]
    {
      Task<string>.Factory.StartNew( () => new System.Net.WebClient().DownloadString(@"http://icanhazip.com").Trim() ),
      Task<string>.Factory.StartNew( () => new System.Net.WebClient().DownloadString(@"http://checkip.dyndns.org").Trim() )
    };

    int index = Task.WaitAny( tasks );
    string ip = tasks[index].Result;

希望这个也有帮助。

0
我是这样做的: 我创建了一个类来保存地理位置数据。
[Serializable]
public class LocationData
{
     public string IP { get; set; }
     public string CountryCode { get; set; }
     public string CountryName { get; set; }
     public string RegionCode { get; set; }
     public string City { get; set; }
     public string ZipCode { get; set; }
     public string TimeZone { get; set; }
     public string Latitude { get; set; }
     public string Longitude { get; set; }
     public string MetroCode { get; set; }
}

然后我使用以下代码调用地理数据并填充类。
public static LocationData GetLocation(string ip= "")
{
    using (var client = new System.Net.WebClient())
    {
         XmlRootAttribute xRoot = new XmlRootAttribute();
         xRoot.ElementName = "Response";
         string downloadedString = client.DownloadString("http://freegeoip.net/xml/" + ip);
           XmlSerializer mySerializer = new XmlSerializer(typeof(LocationData), xRoot) ;
        using (XmlReader xmlReader = XmlReader.Create(new System.IO.StringReader(downloadedString)))
        {
             return mySerializer.Deserialize(xmlReader)as LocationData;
        }
     }
}

由于答案是“坏”的xml,需要指定xRoot元素,否则会出现错误。

编码愉快

沃尔特


0
以下代码将帮助您获取公共 IP 地址。
    string _externalIP;
    _externalIP = (new WebClient()).DownloadString("http://http://icanhazip.com/");
    _externalIP = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"))
                 .Matches(externalIP)[0].ToString();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接