Get public/external IP address?

前端 未结 26 1918
鱼传尺愫
鱼传尺愫 2020-11-22 14:32

I cant seem to get or find information on finding my routers public IP? Is this because it cant be done this way and would have to get it from a website?

相关标签:
26条回答
  • 2020-11-22 14:52

    Basically I prefer to use some extra backups in case if one of IP is not accessible. So I use this method.

     public static string GetExternalIPAddress()
            {
                string result = string.Empty;
                try
                {
                    using (var client = new WebClient())
                    {
                        client.Headers["User-Agent"] =
                        "Mozilla/4.0 (Compatible; Windows NT 5.1; MSIE 6.0) " +
                        "(compatible; MSIE 6.0; Windows NT 5.1; " +
                        ".NET CLR 1.1.4322; .NET CLR 2.0.50727)";
    
                        try
                        {
                            byte[] arr = client.DownloadData("http://checkip.amazonaws.com/");
    
                            string response = System.Text.Encoding.UTF8.GetString(arr);
    
                            result = response.Trim();
                        }
                        catch (WebException)
                        {                       
                        }
                    }
                }
                catch
                {
                }
    
                if (string.IsNullOrEmpty(result))
                {
                    try
                    {
                        result = new WebClient().DownloadString("https://ipinfo.io/ip").Replace("\n", "");
                    }
                    catch
                    {
                    }
                }
    
                if (string.IsNullOrEmpty(result))
                {
                    try
                    {
                        result = new WebClient().DownloadString("https://api.ipify.org").Replace("\n", "");
                    }
                    catch
                    {
                    }
                }
    
                if (string.IsNullOrEmpty(result))
                {
                    try
                    {
                        result = new WebClient().DownloadString("https://icanhazip.com").Replace("\n", "");
                    }
                    catch
                    {
                    }
                }
    
                if (string.IsNullOrEmpty(result))
                {
                    try
                    {
                        result = new WebClient().DownloadString("https://wtfismyip.com/text").Replace("\n", "");
                    }
                    catch
                    {
                    }
                }
    
                if (string.IsNullOrEmpty(result))
                {
                    try
                    {
                        result = new WebClient().DownloadString("http://bot.whatismyipaddress.com/").Replace("\n", "");
                    }
                    catch
                    {
                    }
                }
    
                if (string.IsNullOrEmpty(result))
                {
                    try
                    {
                        string url = "http://checkip.dyndns.org";
                        System.Net.WebRequest req = System.Net.WebRequest.Create(url);
                        System.Net.WebResponse resp = req.GetResponse();
                        System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
                        string response = sr.ReadToEnd().Trim();
                        string[] a = response.Split(':');
                        string a2 = a[1].Substring(1);
                        string[] a3 = a2.Split('<');
                        result = a3[0];
                    }
                    catch (Exception)
                    {
                    }
                }
    
                return result;
            }
    

    In order to update GUI control (WPF, .NET 4.5), for instance some Label I use this code

     void GetPublicIPAddress()
     {
                Task.Factory.StartNew(() =>
                {
                    var ipAddress = SystemHelper.GetExternalIPAddress();
    
                    Action bindData = () =>
                    {
                        if (!string.IsNullOrEmpty(ipAddress))
                            labelMainContent.Content = "IP External: " + ipAddress;
                        else
                            labelMainContent.Content = "IP External: ";
    
                        labelMainContent.Visibility = Visibility.Visible; 
                    };
                    this.Dispatcher.InvokeAsync(bindData);
                });
    
     }
    

    Hope it is useful.

    Here is an example of app that will include this code.

    0 讨论(0)
  • 2020-11-22 14:52

    Answers based on using external web services are not exactly correct, because they do not actually answer the stated question:

    ... information on finding my routers public IP


    Explanation

    All online services return the external IP address, but it does not essentially mean, that this address is assigned to the user's router.

    Router may be assigned with another local IP address of ISP infrastructure networks. Practically this means, that router can not host any services available on Internet. This may be good for safety of most home users, but not good for geeks who host servers at home.

    Here's how to check if router has external IP:

    According to Wikipedia article, the IP address ranges 10.0.0.0 – 10.255.255.255, 172.16.0.0 – 172.31.255.255 and 192.168.0.0 – 192.168.255.255 are used for private i.e. local networks.

    See what happens when you trace route to some remote host with router being assigned with external IP address:

    Gotcha! First hop starts from 31.* now. This clearly means that there's nothing between your router and Internet.


    Solution

    1. Make Ping to some address with Ttl = 2
    2. Evaluate where response comes from.

    TTL=2 must be not enough to reach remote host. Hop #1 host will emit "Reply from <ip address>: TTL expired in transit." revealing its IP address.

    Implementation

    try
    {
        using (var ping = new Ping())
        {
            var pingResult = ping.Send("google.com");
            if (pingResult?.Status == IPStatus.Success)
            {
                pingResult = ping.Send(pingResult.Address, 3000, "ping".ToAsciiBytes(), new PingOptions { Ttl = 2 });
    
                var isRealIp = !Helpers.IsLocalIp(pingResult?.Address);
    
                Console.WriteLine(pingResult?.Address == null
                    ? $"Has {(isRealIp ? string.Empty : "no ")}real IP, status: {pingResult?.Status}"
                    : $"Has {(isRealIp ? string.Empty : "no ")}real IP, response from: {pingResult.Address}, status: {pingResult.Status}");
    
                Console.WriteLine($"ISP assigned REAL EXTERNAL IP to your router, response from: {pingResult?.Address}, status: {pingResult?.Status}");
            }
            else
            {
                Console.WriteLine($"Your router appears to be behind ISP networks, response from: {pingResult?.Address}, status: {pingResult?.Status}");
            }
        }
    }
    catch (Exception exc)
    {
        Console.WriteLine("Failed to resolve external ip address by ping");
    }
    

    Small helper is used to check if IP belongs to private or public network:

    public static bool IsLocalIp(IPAddress ip) {
        var ipParts = ip.ToString().Split(new [] { "." }, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();
    
        return (ipParts[0] == 192 && ipParts[1] == 168) 
            || (ipParts[0] == 172 && ipParts[1] >= 16 && ipParts[1] <= 31) 
            ||  ipParts[0] == 10;
    }
    
    0 讨论(0)
  • 2020-11-22 14:53

    I've refactored @Academy of Programmer's answer to shorter code and altered it so that it only hits https:// URLs:

        public static string GetExternalIPAddress()
        {
            string result = string.Empty;
    
            string[] checkIPUrl =
            {
                "https://ipinfo.io/ip",
                "https://checkip.amazonaws.com/",
                "https://api.ipify.org",
                "https://icanhazip.com",
                "https://wtfismyip.com/text"
            };
    
            using (var client = new WebClient())
            {
                client.Headers["User-Agent"] = "Mozilla/4.0 (Compatible; Windows NT 5.1; MSIE 6.0) " +
                    "(compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
    
                foreach (var url in checkIPUrl)
                {
                    try
                    {
                        result = client.DownloadString(url);
                    }
                    catch
                    {
                    }
    
                    if (!string.IsNullOrEmpty(result))
                        break;
                }
            }
    
            return result.Replace("\n", "").Trim();
        }
    }
    
    0 讨论(0)
  • 2020-11-22 14:57

    I had almost the same as Jesper, only I reused the webclient and disposed it correctly. Also I cleaned up some responses by removing the extra \n at the end.

    
        private static IPAddress GetExternalIp () {
          using (WebClient client = new WebClient()) {
            List<String> hosts = new List<String>();
            hosts.Add("https://icanhazip.com");
            hosts.Add("https://api.ipify.org");
            hosts.Add("https://ipinfo.io/ip");
            hosts.Add("https://wtfismyip.com/text");
            hosts.Add("https://checkip.amazonaws.com/");
            hosts.Add("https://bot.whatismyipaddress.com/");
            hosts.Add("https://ipecho.net/plain");
            foreach (String host in hosts) {
              try {
                String ipAdressString = client.DownloadString(host);
                ipAdressString = ipAdressString.Replace("\n", "");
                return IPAddress.Parse(ipAdressString);
              } catch {
              }
            }
          }
          return null;
        }
    
    
    0 讨论(0)
  • 2020-11-22 14:58
    static void Main(string[] args)
    {
        HTTPGet req = new HTTPGet();
        req.Request("http://checkip.dyndns.org");
        string[] a = req.ResponseBody.Split(':');
        string a2 = a[1].Substring(1);
        string[] a3=a2.Split('<');
        string a4 = a3[0];
        Console.WriteLine(a4);
        Console.ReadLine();
    }
    

    Do this small trick with Check IP DNS

    Use HTTPGet class i found on Goldb-Httpget C#

    0 讨论(0)
  • 2020-11-22 14:58

    You may use Telnet to programmatically query your router for the WAN IP.

    The Telnet part

    The Telnet part can be accomplished using, for example, this Minimalistic Telnet code as an API to send a Telnet command to your router and get the router's response. The remainder of this answer assumes you are set up in one way or another to send a Telnet command and get back the response in your code.

    Limitations of approach

    I will say up front that one drawback of querying the router compared to other approaches is that the code you write is likely to be fairly specific to your router model. That said, it can be a useful approach that doesn't rely on external servers, and you may anyway wish to access your router from your own software for other purposes, such as configuring and controlling it, making it more worthwhile writing specific code.

    Example router command and response

    The example below will not be right for all routers, but illustrates the approach in principle. You will need to change the particulars to suit your router commands and responses.

    For example, the way to get your router to show the WAN IP may be the following Telnet command:

    connection list
    

    The output may consist of a list of lines of text, one per connection, with the IP address at offset 39. The line for the WAN connection may be identifiable from the word "Internet" somewhere in the line:

      RESP: 3947  17.110.226. 13:443       146.200.253. 16:60642     [R..A] Internet      6 tcp   128
    <------------------  39  -------------><--  WAN IP -->
    

    The output may pad each IP address segment out to three characters with spaces, which you will need to remove. (That is, in the xample above, you would need to turn "146.200.253. 16" into "146.200.253.16".)

    By experimentation or consulting reference documentation for your router, you can establish the command to use for your specific router and how to interpret the router's response.

    Code to get the WAN IP

    (Assumes you have a method sendRouterCommand for the Telnet part—see above.)

    Using the example router described above, the following code gets the WAN IP:

    private bool getWanIp(ref string wanIP)
    {
        string routerResponse = sendRouterCommand("connection list");
    
        return (getWanIpFromRouterResponse(routerResponse, out wanIP));
    }
    
    private bool getWanIpFromRouterResponse(string routerResponse, out string ipResult)
    {
        ipResult = null;
        string[] responseLines = routerResponse.Split(new char[] { '\n' });
    
        //  RESP: 3947  17.110.226. 13:443       146.200.253. 16:60642     [R..A] Internet      6 tcp   128
        //<------------------  39  -------------><---  15   --->
    
        const int offset = 39, length = 15;
    
        foreach (string line in responseLines)
        {
            if (line.Length > (offset + length) && line.Contains("Internet"))
            {
                ipResult = line.Substring(39, 15).Replace(" ", "");
                return true;
            }
        }
    
        return false;
    }
    
    0 讨论(0)
提交回复
热议问题