在 Java 中获取“外部”IP 地址
Posted
技术标签:
【中文标题】在 Java 中获取“外部”IP 地址【英文标题】:Getting the 'external' IP address in Java 【发布时间】:2011-02-25 17:20:20 【问题描述】:我不太清楚如何获取机器的外部 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;
【问题讨论】:
您知道一台机器可以同时拥有多个公共地址吗?它们实际上与网络接口相关联,而不是与机器相关联。 【参考方案1】:我不确定您是否可以从本地机器上运行的代码中获取该 IP。
但是,您可以构建在网站上运行的代码,比如在 JSP 中,然后使用返回请求来源 IP 的东西:
request.getRemoteAddr()
或者简单地使用已经存在的服务,然后从服务中解析答案以找出 IP。
使用 AWS 等网络服务
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);
【讨论】:
警告:他们已将自动化 URL 调整为 automation.whatismyip.com/n09230945.asp 我建议至少实施两台为您的 ip 提供服务的服务器,以防其中一台此时出现故障(当然要进行正确的错误处理)。我的选择是externalip.net(单击“需要 API?”链接)。已经使用该网站一年多了,到目前为止还没有遇到任何问题,而且它是一项快速的服务,总是能快速响应。 很棒的链接;我将把它用作大学网络任务概念证明的一部分! 另一种选择是,如果您可以访问运行 php 的 Web 服务器或主机帐户,只需使用上面提供的代码 @bakkal 并将其指向您自己的仅包含echo $_SERVER['REMOTE_ADDR'];
的 PHP 文件。如果这是脚本的唯一或第一行输出,则一切就绪。
Whatsmyip.com 似乎不再支持这种类型的自动化。【参考方案2】:
@stivlo 的其中一个 cmets 值得回答:
您可以使用亚马逊服务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();
【讨论】:
【参考方案3】:事实是:从您提出问题的意义上说,“您不能”。 NAT 发生在协议之外。您的机器内核无法知道您的 NAT 盒子是如何从外部 IP 地址映射到内部 IP 地址的。此处的其他答案提供了一些技巧,涉及与外部网站对话的方法。
【讨论】:
还是不行,因为它没有回答原始问题,而且看起来像是一个学术练习 公平地说,这个答案确实回答了这个问题,而其他十几个答案基本上都说了同样的话,但显示了特定于任何给定外部 ip 检查器选择的代码或 URL。【参考方案4】:所有这些仍然正常运行! (截至 2022 年 2 月 10 日)
http://checkip.amazonaws.com/ https://ipv4.icanhazip.com/ http://myexternalip.com/raw http://ipecho.net/plain http://www.trackip.net/ip忠告:不要直接依赖其中一个;尝试使用一个,但有一个考虑到其他人的应急计划!用得越多越好!
祝你好运!
【讨论】:
【参考方案5】:正如@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
【讨论】:
谢谢!虽然该解决方案在软件位于 NAT 之后时不起作用,但它对于您知道不会位于 NAT 之后的服务器软件仍然非常有帮助,或者如果软件无法连接到另一台服务器以获得它自己的服务器,它仍然非常有用知识产权。特别是对于打算在与 Internet 断开连接的 LAN 上运行的软件,这是可行的方法。【参考方案6】:创建一个到 www.whatismyip.com 之类的网站的 HttpURLConnection 并解析它:-)
【讨论】:
【参考方案7】:这个怎么样?这很简单,对我来说效果最好:)
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();
【讨论】:
这太棒了!我回家后会试试的。这正是我一直在寻找的解决问题的方法。不知道为什么它没有被投票更高。【参考方案8】:http://jstun.javawi.de/ 会做 - 只要你的网关设备做 STUN )大多数做)
【讨论】:
非常有趣,它按预期工作,无需使用外部服务,只需与网关对话。然而,GPL 许可可能会限制其采用。 网站给了我一个登录屏幕。可能不是原版。【参考方案9】:这并不容易,因为局域网内的机器通常不关心其路由器到互联网的外部 IP。它根本不需要它!
我建议您通过打开类似http://www.whatismyip.com/ 的网站并通过解析 html 结果获取 IP 号来利用此功能。这应该不难!
【讨论】:
您不必解析 html。 whatismyip.com的网页来源第一行就是你的外网IP。【参考方案10】:import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.regex.Pattern;
public class ExternalIPUtil
private static final Pattern IPV4_PATTERN = Pattern.compile("^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.)3([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");
private static final String[] IPV4_SERVICES =
"http://checkip.amazonaws.com/",
"https://ipv4.icanhazip.com/",
"http://bot.whatismyipaddress.com/"
// and so on ...
;
public static String get() throws ExecutionException, InterruptedException
List<Callable<String>> callables = new ArrayList<>();
for (String ipService : IPV4_SERVICES)
callables.add(() -> get(ipService));
ExecutorService executorService = Executors.newCachedThreadPool();
try
return executorService.invokeAny(callables);
finally
executorService.shutdown();
private static String get(String url) throws IOException
try (BufferedReader in = new BufferedReader(new InputStreamReader(new URL(url).openStream())))
String ip = in.readLine();
if (IPV4_PATTERN.matcher(ip).matches())
return ip;
else
throw new IOException("invalid IPv4 address: " + ip);
public static void main(String[] args) throws ExecutionException, InterruptedException
System.out.println("IP: " + get());
同时从多个 IP 服务获取,例如:
http://checkip.amazonaws.com/ https://ipv4.icanhazip.com/ http://bot.whatismyipaddress.com/ 等等...和ExecutorService.invokeAny(tasks)
返回第一个成功线程的结果。其他未完成的任务将被取消。
【讨论】:
【参考方案11】:如果您使用的是基于 JAVA 的 webapp,并且如果您想获取客户端(通过浏览器发出请求的人)的外部 ip,请尝试在 公共域 中部署该应用并使用 request.getRemoteAddr () 读取外部 IP 地址。
【讨论】:
【参考方案12】:System.out.println(pageCrawling.getHtmlFromURL("http://ipecho.net/plain"));
【讨论】:
【参考方案13】:另一种解决方案是执行外部命令,显然,这种解决方案限制了应用程序的可移植性。
例如,对于在 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;
【讨论】:
以上是关于在 Java 中获取“外部”IP 地址的主要内容,如果未能解决你的问题,请参考以下文章
LogParser 查询仅从 IIS 日志中获取外部 IP 地址?
您可以从 Google Compute VM 实例中获取外部 IP 地址吗?