如何以编程方式获取公共 IP 地址?

Posted

技术标签:

【中文标题】如何以编程方式获取公共 IP 地址?【英文标题】:How to programmatically get a public IP address? 【发布时间】:2018-05-28 12:21:31 【问题描述】:

我没有找到正确的解决方案。下面的代码给了我本地 IP 地址(如果我连接到 Wifi,它会给出类似 192.168.0.x 的 IP 地址),但我想要公共 IP 地址(就像我在 google 中搜索“我的 IP 是什么”一样)

public static String getLocalIpAddress() 
try 
    for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) 
        NetworkInterface intf = en.nextElement();
        for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) 
            InetAddress inetAddress = enumIpAddr.nextElement();
            if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) 
                return inetAddress.getHostAddress();
            
        
    
 catch (SocketException ex) 
    ex.printStackTrace();

return null;

WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
    String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());

有人可以帮忙吗?谢谢!

【问题讨论】:

How to get IP address of the device from code?的可能重复 【参考方案1】:

第 1 步:创建一个返回请求者 IP 地址的 Web 服务

第 2 步:从您的应用中调用该 Web 服务。

设备不知道其公共 IP 地址(除非该设备严重配置错误)。

【讨论】:

其他答案让我抓狂。非常感谢!【参考方案2】:

您可以使用whatismyip.com 中的WS https://api.whatismyip.com/ip.php :这只会以简单文本形式输出您的IP 地址。 (无需输入,输出可选)

您必须是金牌会员才能访问 API

更新答案

您可以使用ipify.org的网络服务

阅读文档here

使用https://api.ipify.org/?format=jsonWS 获取设备公网IP地址。这将以 JSON 格式输出您的 IP 地址。

您应该使用 ipify,因为:

您可以无限制地使用它(即使您每分钟处理数百万个请求)。 它始终在线且可用,其基础架构由 Heroku 提供支持,这意味着无论运行 API 的服务器是否死机,或者是否有一场巨大的龙卷风摧毁了东海岸的一半,ipify 仍将运行! 它可以完美地处理 IPv4 和 IPv6 地址,因此无论您使用哪种技术,都不会出现问题。

........

........

【讨论】:

Use http://api.whatismyip.com/ip.php WS to get device public IP address 这不起作用。发帖前你试过了吗? 您必须是金牌会员才能访问 API。您是 WhatIsMyIP.com 的金牌会员吗? 在需要成为会员的情况下使用服务器没有多大意义。你为什么不马上告诉? 他们有几十年了。就像你提到的那个。没有区别。 确保您的隐私政策指出您是通过其他人的 Web 服务而不是您自己的 Web 服务发出这些请求。【参考方案3】:

我找到了这个简单的解决方案:

public String getExternalIpAddress() throws Exception 
    URL whatismyip = new URL("http://checkip.amazonaws.com");
    BufferedReader in = null;
    try 
        in = new BufferedReader(new InputStreamReader(
                whatismyip.openStream()));
        String ip = in.readLine();
        return ip;
     finally 
        if (in != null) 
            try 
                in.close();
             catch (IOException e) 
                e.printStackTrace();
            
        
    

请记住,这必须在单独的线程上运行。

【讨论】:

在线提供了很棒的解决方案:) 这个api有没有最大使用限制?【参考方案4】:

你可以用一个简单的线程来做到这一点。 您需要在 Activity.class 文件中创建一个函数,并且需要请求一个 url 以文本形式提供您的公共 IP:“https://api.ipify.org/.Click to open.

在你的 onCreate() 函数中添加这个函数调用。

    getPublicIP();

在你的 MainActivity.class 中添加这个函数。

    private void getPublicIP() 

        new Thread(new Runnable()
            public void run()
                //TextView t; //to show the result, please declare and find it inside onCreate()

                try 
                    // Create a URL for the desired page
                    URL url = new URL("https://api.ipify.org/"); //My text file location
                    //First open the connection
                    HttpURLConnection conn=(HttpURLConnection) url.openConnection();
                    conn.setConnectTimeout(60000); // timing out in a minute

                    BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));

                    //t=(TextView)findViewById(R.id.TextView1); // ideally do this in onCreate()
                    String str;
                    while ((str = in.readLine()) != null) 
                        urls.add(str);
                    
                    in.close();
                 catch (Exception e) 
                    Log.d("MyTag",e.toString());
                

                //since we are in background thread, to post results we have to go back to ui thread. do the following for that

                PermissionsActivity.this.runOnUiThread(new Runnable()
                    public void run()
                        try 
                            Toast.makeText(PermissionsActivity.this, "Public IP:"+urls.get(0), Toast.LENGTH_SHORT).show();
                        
                        catch (Exception e)
                            Toast.makeText(PermissionsActivity.this, "TurnOn wiffi to get public ip", Toast.LENGTH_SHORT).show();
                        
                    
                );

            
        ).start();

    

【讨论】:

【参考方案5】:

调用https://whatismyipaddress.com 或http://howtofindmyipaddress.com/ 等服务器。

如果你有页面源然后解析出 ip 地址。

还有其他服务器只返回您的 IP 地址。不是上面两个的整个html页面。但是我忘记是哪一个了...

【讨论】:

确保您的隐私政策指出您是通过其他人的 Web 服务而不是您自己的 Web 服务发出这些请求。

以上是关于如何以编程方式获取公共 IP 地址?的主要内容,如果未能解决你的问题,请参考以下文章

获取公共/外部 IP 地址?

以编程方式发现公共 IP

如何在C#中获取用户的公共IP地址

如何使用 PHP 获取服务器的公共 IP 地址?

如何使用 Ruby SDK 从 AWS 获取公共 IP 地址

如何在servlet java中获取客户端公共IP地址[重复]