java InetAddress.getLocalHost(); 返回127.0.0.1 ...如何获得REAL IP?

got*_*ch4 52 java networking

我正在写一个简单的网络应用程序......我需要知道我的机器在网络上的真实IP,如192.168.1.3.getLocalHost返回127.0.0.1(在Linux上,dunno,如果它在Windows上是相同的)怎么做?

Eri*_*ric 33

如果您确实想要使用计算机上的所有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());
                        }
                }
        }
}
Run Code Online (Sandbox Code Playgroud)

  • `while(x.hasMoreElements()){}`比`for(; x.hasMoreElements();){}更整洁 (17认同)

sfu*_*ger 21

由于机器可能有多个地址,因此很难确定哪一个适合您.通常,您希望系统根据其路由表分配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());
Run Code Online (Sandbox Code Playgroud)

我不确定在没有建立连接的情况下是否可以这样做.我想我曾经设法用Perl(或C?)来做,但不要问我关于Java的问题.我认为有可能创建UDP套接字(DatagramSocket)而不实际连接它.

如果路上有NAT路由器,您将无法获得远程主机将看到的IP.但是,正如你给192.*举个例子,我觉得你不在乎.


小智 18

要解决这个问题:

  1. 找到您的主机名.类型:hostname.例如,您发现您的主机名是mycomputer.xzy.com

  2. 将主机名放在hosts文件中./etc/hosts.如

    10.50.16.136 mycomputer.xzy.com
    
    Run Code Online (Sandbox Code Playgroud)


bol*_*y38 11

这是一种避免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;
        }
Run Code Online (Sandbox Code Playgroud)


che*_*cho 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]);
}
Run Code Online (Sandbox Code Playgroud)

核实!

为了我:

  • 一定不是LoopBack!
  • 必须UP!
  • 必须有 MAC 地址(不为空)


Pau*_*lin 3

您的计算机可能有多个 IP。你怎么知道是哪一个?我的方法是在另一台机器上运行一个非常简单的 CGI,报告它所看到的 IP,当我需要知道我的 IP 对外界来说是什么样子时,我就这么做了。