在Java中获取“外部” IP地址


83

我不太确定如何获取计算机的外部IP地址,就像网络外部的计算机会看到它一样。

我下面的IPAddress类仅获取计算机的本地IP地址。

public class IPAddress {

    private InetAddress thisIp;

    private String thisIpAddress;

    private void setIpAdd() {
        try {
            InetAddress thisIp = InetAddress.getLocalHost();
            thisIpAddress = thisIp.getHostAddress().toString();
        } catch (Exception e) {
        }
    }

    protected String getIpAddress() {
        setIpAdd();
        return thisIpAddress;
    }
}

13
您知道一台机器可以一次拥有多个公共地址吗?它们实际上与网络接口关联,而不是与计算机关联。
Donal Fellows 2010年

Answers:


168

我不确定是否可以从在本地计算机上运行的代码中获取该IP。

但是,您可以构建在网站上运行的代码(例如,在JSP中),然后使用返回请求来源IP的内容:

request.getRemoteAddr()

或者只是使用已经存在的服务来执行此操作,然后解析该服务的答案以找到IP。

使用AWS等Web服务

import java.net.*;
import java.io.*;

URL whatismyip = new URL("http://checkip.amazonaws.com");
BufferedReader in = new BufferedReader(new InputStreamReader(
                whatismyip.openStream()));

String ip = in.readLine(); //you get the IP as a String
System.out.println(ip);

4
警告词:他们已将自动化URL调整为automation.whatismyip.com/n09230945.asp
thegrinner 2011年

8
我建议至少实现两台为您的ip服务的服务器,以防其中一台服务器目前停机(当然,要进行正确的错误处理)。我的选择是externalip.net(单击“需要API?”链接)。现在已经使用该网站已有一年多了,到目前为止还没有出现任何问题,它是一种快速的服务,总是可以快速响应。

很棒的链接;我将在大学网络作业中将其用作概念证明的一部分!
araisbec 2012年

另一个选择是,如果您可以访问运行PHP的Web服务器或主机帐户,只需使用上面提供的代码@bakkal并将其指向您自己的包含的PHP文件echo $_SERVER['REMOTE_ADDR'];。如果这是脚本的唯一或第一行输出,那么您都已设置好。
Kingsolmn

7
Whatsmyip.com似乎不再支持这种类型的自动化。
2013年

79

@stivlo的其中一项评论值得一提:

您可以使用Amazon服务http://checkip.amazonaws.com

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;

public class IpChecker {

    public static String getIp() 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();
                }
            }
        }
    }
}

19

事实是:就您提出的问题而言,“您不能”。NAT发生在协议之外。您的计算机内核无法知道NAT盒是如何从外部IP地址映射到内部IP地址的。这里的其他答案提供了一些技巧,涉及与外部网站进行交谈的方法。


3
是否可以接受,因为它不能回答原始问题,而且看起来像是一项学术练习
Bruno Bossola 2015年

公平地说,此答案确实回答了问题,其他十二个答案基本上都说相同的话,但显示了特定于任何给定外部IP检查器选择的代码或URL。
Thomas Carlisle

14

所有这一切仍在进行中,并且工作顺利!(截至2019年9月23日)

建议:不要仅仅依靠其中之一;尝试使用其中一个,但要考虑其他人的应急计划!您使用的越多越好!

祝好运!


12

正如@Donal Fellows所写,您必须查询网络接口而不是计算机。来自javadocs的这段代码对我有用:

以下示例程序列出了计算机上的所有网络接口及其地址:

import java.io.*;
import java.net.*;
import java.util.*;
import static java.lang.System.out;

public class ListNets {

    public static void main(String args[]) throws SocketException {
        Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
        for (NetworkInterface netint : Collections.list(nets))
            displayInterfaceInformation(netint);
    }

    static void displayInterfaceInformation(NetworkInterface netint) throws SocketException {
        out.printf("Display name: %s\n", netint.getDisplayName());
        out.printf("Name: %s\n", netint.getName());
        Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
        for (InetAddress inetAddress : Collections.list(inetAddresses)) {
            out.printf("InetAddress: %s\n", inetAddress);
        }
        out.printf("\n");
     }
} 

以下是示例程序的输出示例:

Display name: TCP Loopback interface
Name: lo
InetAddress: /127.0.0.1

Display name: Wireless Network Connection
Name: eth0
InetAddress: /192.0.2.0

来自docs.oracle.com


1
谢谢!虽然该解决方案在软件位于NAT之后时不起作用,但是对于您知道不会在NAT之后的服务器软件还是非常有用的,如果软件无法连接到另一台服务器以获取自己的软件,则该解决方案将对您有帮助IP。特别是对于打算在与Internet断开连接的LAN上运行的软件,这是必经之路。
pavon 2012年

6

建立一个类似于www.whatismyip.com之类的站点的HttpURLConnection并解析:-)


5

这个怎么样?这很简单,对我来说效果最好:)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;


public class IP {
    public static void main(String args[]) {
        new IP();
    }

    public IP() {
        URL ipAdress;

        try {
            ipAdress = new URL("http://myexternalip.com/raw");

            BufferedReader in = new BufferedReader(new InputStreamReader(ipAdress.openStream()));

            String ip = in.readLine();
            System.out.println(ip);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

太好了!到家时我会尝试的。这正是我所寻找的解决问题的方式。不知道为什么它没有得到更高的投票。
亚当893

4

http://jstun.javawi.de/会做到这一点-只要您的网关设备执行STUN)


1
非常有趣的是,它在不使用外部服务的情况下可以按预期工作,而只是与网关对话。但是,GPL许可证可能会限制其采用。
Bruno Bossola 2015年

网站给我一个登录屏幕。可能不是原始的。
2016年

1

这不是那么容易,因为局域网内的计算机通常并不关心路由器到Internet的外部IP ..它根本不需要它!

我建议您通过打开一个类似http://www.whatismyip.com/的网站并通过解析html结果获取IP地址来利用这一点。这不应该那么难!


2
您不必解析html。whatismyip.com网页来源的第一行是您的外部IP。
马丁·考特

0

如果您正在使用基于JAVA的Web应用程序,并且要获取客户端(通过浏览器发出请求的人)的外部IP,请尝试在公共域中部署该应用程序,并使用request.getRemoteAddr()读取外部IP地址。



0

另一种解决方案是执行外部命令,显然,该解决方案限制了应用程序的可移植性。

例如,对于在Windows上运行的应用程序,可以通过jPowershell执行PowerShell命令,如以下代码所示:

public String getMyPublicIp() {
    // PowerShell command
    String command = "(Invoke-WebRequest ifconfig.me/ip).Content.Trim()";
    String powerShellOut = PowerShell.executeSingleCommand(command).getCommandOutput();

    // Connection failed
    if (powerShellOut.contains("InvalidOperation")) {
        powerShellOut = null;
    }
    return powerShellOut;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.