获取公共Internet IP地址/地理位置的智能方式

时间:2011-02-02 21:03:37

标签: c# .net geolocation ip-address

我在本地网络上有一台计算机,位于NAT路由器后面。我有一些192.168.0.x地址,但我真的想知道我的公共 IP地址,而不是

中提到的

How to get the IP address of the server on which my C# application is running on?

How to get the IP address of a machine in C#

我需要C#代码。

有可能吗?如果是这样,怎么样?

9 个答案:

答案 0 :(得分:24)

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

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

答案 1 :(得分:6)

经过一些搜索,并通过扩展我的要求,我发现这不仅会让我获得IP,还会获得GEO位置:

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;
}

答案 2 :(得分:5)

问题是您要查找的IP地址不属于您的计算机。它属于您的NAT路由器。我能想到的唯一方法是使用外部服务器或者使用某种方式查询路由器。

如果您的路由器支持SNMP,您可以这样做。

答案 3 :(得分:2)

我相信你真的需要连接一些服务器才能获得你的外部IP。

答案 4 :(得分:2)

根据您使用的路由器,您可能直接从路由器获取路由器的可能性非常大。他们中的大多数都有一个Web界面,因此可以导航到正确的网页(例如,“192.168.0.1/whatever”)和“抓取”该页面的外部IP地址。当然,问题在于它非常脆弱 - 如果你改变(甚至重新配置)你的路由器,很可能会破坏它。

答案 5 :(得分:2)

如果失败,你可以使用uPNP并回到whatsmyip.com。

答案 6 :(得分: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;

希望这个也有所帮助。

答案 7 :(得分: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元素,否则会出错。

快乐编码

沃尔特

答案 8 :(得分: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();