java InetAddress.getLocalHost();返回 127.0.0.1 ...如何获得真实 IP?
Posted
技术标签:
【中文标题】java InetAddress.getLocalHost();返回 127.0.0.1 ...如何获得真实 IP?【英文标题】:java InetAddress.getLocalHost(); returns 127.0.0.1 ... how to get REAL IP? 【发布时间】:2011-01-23 18:58:39 【问题描述】:我正在编写一个简单的网络应用程序。我需要知道我的机器在网络上的真实 IP,比如 192.168.1.3 。 getLocalHost 返回 127.0.0.1 (在Linux上,不知道在windows上是不是一样)。怎么做?
【问题讨论】:
在我的窗口中,System.out.println(InetAddress.getLocalHost().getHostAddress());打印 10.50.16.136 有趣...正确答案,虽然它不起作用? 这在 SO 上很常见,错误的回答会被标记为已回答。 @sfussenegger 127.0.1.1 是 Debian 的东西(Ubuntu 是从它衍生而来的)。 IIRC,如果你使用 DHCP,你会得到它。这允许报告一个固定的 IP 地址(我相信这对于 GNOME 的顺利运行是必要的)。所以 127.0.1.1 是一个“真实 IP”地址。 (顺便说一句:192.168.* 是非互联网 IP 地址。) @tom 是的,我知道它是什么。我只是想知道这是对这个问题的正确答案(“我需要知道我的机器在网络上的真实 ip”)。 【参考方案1】:如果您真的想使用机器上的所有 IP 地址,您可以使用 NetworkInterface 类获取这些地址。当然,您需要实际使用哪一个,但这取决于您使用它的目的,或者您可能需要扩展使用它的方式以考虑多个地址。
import java.net.*;
import java.util.*;
public class ShowInterfaces
public static void main(String[] args) throws Exception
System.out.println("Host addr: " + InetAddress.getLocalHost().getHostAddress()); // often returns "127.0.0.1"
Enumeration<NetworkInterface> n = NetworkInterface.getNetworkInterfaces();
for (; n.hasMoreElements();)
NetworkInterface e = n.nextElement();
System.out.println("Interface: " + e.getName());
Enumeration<InetAddress> a = e.getInetAddresses();
for (; a.hasMoreElements();)
InetAddress addr = a.nextElement();
System.out.println(" " + addr.getHostAddress());
【讨论】:
while (x.hasMoreElements())
会比 for (;x.hasMoreElements();)
更整洁【参考方案2】:
由于机器可能有多个地址,因此很难确定哪一个适合您。通常,您希望系统根据其路由表分配 IP。由于结果取决于您要连接的 IP,因此有一个简单的技巧:只需创建一个连接并查看您从操作系统获得的地址:
// output on my machine: "192.168.1.102"
Socket s = new Socket("192.168.1.1", 80);
System.out.println(s.getLocalAddress().getHostAddress());
s.close();
// output on my machine: "127.0.1.1"
System.out.println(InetAddress.getLocalHost().getHostAddress());
我不确定是否可以在不建立连接的情况下执行此操作。我想我曾经设法用 Perl(或 C?)做到这一点,但不要问我关于 Java 的事。我认为有可能在不实际连接的情况下创建一个 UDP 套接字(DatagramSocket)。
如果途中有 NAT 路由器,您将无法获得远程主机将看到的 IP。但是,正如您以 192.* 为例,我认为您不在乎。
【讨论】:
但是你怎么知道网关IP(192.168.1.1)首先打开套接字? @mrod 你应该使用“你想连接的IP”。例如,您可以使用new Socket("www.google.com", 80);
来获取路由到 Internet 的接口的 IP 地址
对,如果我们假设用例是“连接到另一台主机”,这将起作用:)。如果用例是审计或任何其他没有与另一台主机连接的情况,我猜如果配置了多个 IP 地址(除非我们知道特定的首选子网,例如)
@mrod 大约 12 年前我从事过一个审计项目,我认为(正如我所提到的)我们使用 Perl 或 C 来创建 UDP 包而没有发送任何实际包并读取包的源地址。并且给定一台具有多个网络接口的机器,问题中使用的术语“真实 IP”可以说取决于目的地。否则这种方法将无济于事。【参考方案3】:
修复它:
找到您的主机名。类型:hostname
。例如,您发现您的主机名是mycomputer.xzy.com
将您的主机名放入您的主机文件中。 /etc/hosts
。比如
10.50.16.136 mycomputer.xzy.com
【讨论】:
这对我来说是“修复”它的奇怪方式:如果你的应用程序的主机 IP 发生变化,你就死定了..【参考方案4】:这是一种避免 IPv6 和 Loopback 结果的方法。
public InetAddress getCurrentIp()
try
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface
.getNetworkInterfaces();
while (networkInterfaces.hasMoreElements())
NetworkInterface ni = (NetworkInterface) networkInterfaces
.nextElement();
Enumeration<InetAddress> nias = ni.getInetAddresses();
while(nias.hasMoreElements())
InetAddress ia= (InetAddress) nias.nextElement();
if (!ia.isLinkLocalAddress()
&& !ia.isLoopbackAddress()
&& ia instanceof Inet4Address)
return ia;
catch (SocketException e)
LOG.error("unable to get current IP " + e.getMessage(), e);
return null;
【讨论】:
【参考方案5】:我写了这段代码:
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
private String[] getHostAddresses()
Set<String> HostAddresses = new HashSet<>();
try
for (NetworkInterface ni : Collections.list(NetworkInterface.getNetworkInterfaces()))
if (!ni.isLoopback() && ni.isUp() && ni.getHardwareAddress() != null)
for (InterfaceAddress ia : ni.getInterfaceAddresses())
if (ia.getBroadcast() != null) //If limited to IPV4
HostAddresses.add(ia.getAddress().getHostAddress());
catch (SocketException e)
return HostAddresses.toArray(new String[0]);
检查一下!
对我来说:
不能是 LoopBack! 必须启动! 必须有 MAC 地址(不为空)【讨论】:
【参考方案6】:您的计算机可能有多个 IP。你怎么知道是哪一个?我这样做的方法是在另一台机器上运行一个非常简单的 CGI,它会报告它所看到的 IP,当我需要知道我的 IP 在外界看来是什么样子时,我会点击它。
【讨论】:
【参考方案7】:我没有使用 InetAddress.getHostAddress(),而是调用我编写的 getHost4Address 例程来获取第一个非环回地址...
/**
* Returns this host's non-loopback IPv4 addresses.
*
* @return
* @throws SocketException
*/
private static List<Inet4Address> getInet4Addresses() throws SocketException
List<Inet4Address> ret = new ArrayList<Inet4Address>();
Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
for (NetworkInterface netint : Collections.list(nets))
Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
for (InetAddress inetAddress : Collections.list(inetAddresses))
if (inetAddress instanceof Inet4Address && !inetAddress.isLoopbackAddress())
ret.add((Inet4Address)inetAddress);
return ret;
/**
* Returns this host's first non-loopback IPv4 address string in textual
* representation.
*
* @return
* @throws SocketException
*/
private static String getHost4Address() throws SocketException
List<Inet4Address> inet4 = getInet4Addresses();
return !inet4.isEmpty()
? inet4.get(0).getHostAddress()
: null;
【讨论】:
【参考方案8】:从当前实例获取当前请求
HttpServletRequest httpServletRequest = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
然后从请求中获取地址
ip = httpServletRequest.getRemoteAddr();
【讨论】:
包含关于代码/解决方案的简介将使这个答案成为一个完整的答案! 这个答案感觉是正确的。我正在寻找对我的服务器的 smpp 请求的客户端请求地址 FacesContext 不是 JDK 的一部分,它是 JSF 实现的一部分。 OP 没有提到 JSF afaik。【参考方案9】:获取当前框匹配模式的ip地址:
import java.io.*;
import java.util.*;
import java.util.regex.Pattern;
String ipPattern = "(192.1.200.)(\\d)1,3"; //your organization pattern
try
Enumeration en = NetworkInterface.getNetworkInterfaces();
while (en.hasMoreElements())
NetworkInterface ni = (NetworkInterface) en.nextElement();
Enumeration ee = ni.getInetAddresses();
while (ee.hasMoreElements())
InetAddress ia = (InetAddress) ee.nextElement();
String ip = ia.getHostAddress();
System.out.println("ip: '" + ip + "'\n");
boolean matched = Pattern.matches(ipPattern, ip);
if (matched)
System.out.println("matched\n");
catch(Exception e)
结果:
ip: 'fe80:0:0:0:510a:528b:7204:39d0%enp0s25'
ip: '192.1.200.3'
matched
ip: '0:0:0:0:0:0:0:1%lo'
ip: '127.0.0.1'
【讨论】:
这个答案被删除了,因为它只是一个代码,我通过添加一个标题来拯救它,使代码更加自我记录并显示结果。将来,如果答案只是代码,没有任何解释,那么它通常会被自动标记。 如果我们改变组织怎么办?【参考方案10】:我遇到同样问题的最短解决方案
搜索后发现PCHsotName在"/etc/hosts"文件中得到了127.0.1.1 IP地址
1) 所以使用任何编辑器打开文件 /etc/hosts
我用过纳米
$ sudo nano /etc/hosts
2) 并在行首添加“#”
127.0.1.1 HostName
喜欢
#127.0.1.1 HostName
3) ctrl+o 保存
4) ctrl+x 退出 nano 编辑器
注意:“主机名”取决于您的计算机或服务器的名称。
【讨论】:
【参考方案11】:如果你想获得你电脑的IP地址,你必须使用“java.net.InetAddress”库中的“InetAddress”对象。
以下方法返回你的IP:
public String getIp()
String myIp = "";
InetAddress ip;
try
ip = InetAddress.getLocalHost();
myIp = ip.getHostAddress(); // This method returns the IP.
catch (UnknownHostException e)
e.printStackTrace();
return myIp;
【讨论】:
此代码可能返回环回地址(如果 hosts 未修改) 原问题说如何避免环回地址,这段代码会返回相同的。以上是关于java InetAddress.getLocalHost();返回 127.0.0.1 ...如何获得真实 IP?的主要内容,如果未能解决你的问题,请参考以下文章