java InetAddress.getLocalHost();返回127.0.0.1。。。如何获得真正的IP?

java InetAddress.getLocalHost();返回127.0.0.1。。。如何获得真正的IP?,java,networking,Java,Networking,我正在编写一个简单的网络应用程序。我需要知道我的机器在网络上的真实IP,比如192.168.1.3。getLocalHost返回127.0.0.1(在Linux上,我不知道在windows上是否相同)。如何操作?您的计算机可能有多个IP。你怎么知道是哪一个?我这样做的方式是在另一台机器上运行一个非常简单的CGI,它会报告它看到的IP,当我需要知道我的IP在外部世界看起来是什么样子时,我会点击这个按钮。由于这台机器可能有多个地址,很难确定哪个地址适合你。通常,您希望系统根据其路由表分配IP。由于结

我正在编写一个简单的网络应用程序。我需要知道我的机器在网络上的真实IP,比如192.168.1.3。getLocalHost返回127.0.0.1(在Linux上,我不知道在windows上是否相同)。如何操作?

您的计算机可能有多个IP。你怎么知道是哪一个?我这样做的方式是在另一台机器上运行一个非常简单的CGI,它会报告它看到的IP,当我需要知道我的IP在外部世界看起来是什么样子时,我会点击这个按钮。

由于这台机器可能有多个地址,很难确定哪个地址适合你。通常,您希望系统根据其路由表分配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地址,您可以使用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());
                        }
                }
        }
}
import java.net.*;
导入java.util.*;
公共类显示接口
{
公共静态void main(字符串[]args)引发异常
{
System.out.println(“主机地址:+InetAddress.getLocalHost().getHostAddress());//通常返回“127.0.0.1”
枚举n=NetworkInterface.getNetworkInterfaces();
对于(;n.hasMoreElements();)
{
网络接口e=n.nextElement();
System.out.println(“接口:+e.getName());
枚举a=e.getInetAddresses();
对于(;a.hasMoreElements();)
{
InetAddress addr=a.nextElement();
System.out.println(“+addr.getHostAddress());
}
}
}
}
要修复它:

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

  • 将主机名放入主机文件中<代码>/etc/hosts。比如

    10.50.16.136 mycomputer.xzy.com
    

  • 下面是一种避免IPv6和环回结果的方法

    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;
            }
    
    public InetAddress getCurrentIp(){
    试一试{
    枚举网络接口=网络接口
    .getNetworkInterfaces();
    while(networkInterfaces.hasMoreElements()){
    网络接口ni=(网络接口)网络接口
    .nextElement();
    枚举nias=ni.getInetAddresses();
    while(nias.hasMoreElements()){
    InetAddress ia=(InetAddress)nias.nextElement();
    如果(!ia.isLinkLocalAddress()
    &&!ia.isLoopbackAddress()
    &&ia实例(Inet4Address){
    返回ia;
    }
    }
    }
    }捕获(SocketException e){
    LOG.error(“无法获取当前IP”+e.getMessage(),e);
    }
    返回null;
    }
    
    从当前实例获取当前请求

    HttpServletRequest httpServletRequest = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
    
    然后从请求中获取地址

    ip = httpServletRequest.getRemoteAddr();
    

    如果您想获取PC的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;
    }
    

    我没有使用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;
    }
    
    /**
    *返回此主机的非环回IPv4地址。
    * 
    *@返回
    *@SocketException
    */
    私有静态列表getInet4Addresses()引发SocketException{
    List ret=new ArrayList();
    枚举网络=NetworkInterface.getNetworkInterfaces();
    用于(网络接口netint:Collections.list(nets)){
    枚举inetAddresses=netint.getInetAddresses();
    用于(InetAddress:Collections.list(inetAddresses)){
    if(Inet4Address的inetAddress实例&!inetAddress.isLoopbackAddress()){
    ret.add((Inet4Address)inetAddress);
    }
    }
    }
    返回ret;
    }
    /**
    *以文本形式返回此主机的第一个非环回IPv4地址字符串
    *代表性。
    * 
    *@返回
    *@SocketException
    */
    私有静态字符串getHost4Address()引发SocketException{
    List inet4=getInet4Addresses();
    return!inet4.isEmpty()
    ?inet4.get(0).getHostAddress()
    :null;
    }
    
    我写了以下代码:

    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]);
    }
    
    导入java.net.InterfaceAddress;
    导入java.net.NetworkInterface;
    导入java.util.Collections;
    导入java.util.HashSet;
    导入java.util.Set;
    私有字符串[]getHostAddresses(){
    Set HostAddresses=newhashset();
    试一试{
    for(NetworkInterface ni:Collections.list(NetworkInterface.getNetworkInterfaces())){
    如果(!ni.isLoopback()&&ni.isUp()&&ni.getHardwareAddress()!=null){
    对于(InterfaceAddress ia:ni.getInterfaceAddresses()){
    如果(ia.getBroadcast()!=null){//如果仅限于IPV4
    添加(ia.getAddress().getHostAddress());
    }
    }
    }
    }
    }
    
    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'
    
    $ sudo nano /etc/hosts
    
    127.0.1.1 HostName
    
    #127.0.1.1 HostName