使用Java获取当前计算机的IP地址

sas*_*har 274 java sockets ip

我正在尝试开发一个系统,其中有不同的节点在不同的系统或同一系统上的不同端口上运行.

现在,所有节点都创建一个Socket,其目标IP作为称为引导节点的特殊节点的IP.然后节点创建自己的节点ServerSocket并开始侦听连接.

引导节点维护一个节点列表,并在被查询时返回它们.

现在我需要的是节点必须将其IP注册到自举节点.我尝试使用cli.getInetAddress()一旦客户端连接到ServerSocketbootstrapping节点,但这不起作用.

  1. 我需要客户端注册其PPP IP(如果可用);
  2. 否则LAN IP如果可用;
  3. 否则它必须注册127.0.0.1,假设它是同一台计算机.

使用代码:

System.out.println(Inet4Address.getLocalHost().getHostAddress());
Run Code Online (Sandbox Code Playgroud)

要么

System.out.println(InetAddress.getLocalHost().getHostAddress());
Run Code Online (Sandbox Code Playgroud)

我的PPP连接IP地址是:117.204.44.192,但上面的返回值为192.168.1.2

编辑

我使用以下代码:

Enumeration e = NetworkInterface.getNetworkInterfaces();
while(e.hasMoreElements())
{
    NetworkInterface n = (NetworkInterface) e.nextElement();
    Enumeration ee = n.getInetAddresses();
    while (ee.hasMoreElements())
    {
        InetAddress i = (InetAddress) ee.nextElement();
        System.out.println(i.getHostAddress());
    }
}
Run Code Online (Sandbox Code Playgroud)

我能够获得所有相关的所有IP地址NetworkInterface,但我如何区分它们?这是我得到的输出:

127.0.0.1
192.168.1.2
192.168.56.1
117.204.44.19
Run Code Online (Sandbox Code Playgroud)

Ste*_*n C 264

在最一般的情况下,这可能有点棘手.

从表面上看,InetAddress.getLocalHost()应该给你这个主机的IP地址.问题是主机可能有很多网络接口,接口可能绑定到多个IP地址.最重要的是,并非所有IP地址都可以在您的机器或LAN之外访问.例如,它们可以是虚拟网络设备的IP地址,专用网络IP地址等.

这意味着返回的IP地址InetAddress.getLocalHost()可能不是正确的IP地址.

你怎么处理这个?

  • 一种方法是使用NetworkInterface.getNetworkInterfaces()获取主机上的所有已知网络接口,然后迭代每个NI的地址.
  • 另一种方法是(以某种方式)获取主机的外部广告FQDN,并用于InetAddress.getByName()查找主IP地址.(但是你如何得到它,以及如何处理基于DNS的负载均衡器?)
  • 前一个版本的变体是从配置文件或命令行参数中获取首选FQDN.
  • 另一种变体是从配置文件或命令行参数中获取首选IP地址.

总之,InetAddress.getLocalHost()通常会起作用,但您可能需要为在具有"复杂"网络的环境中运行代码的情况提供替代方法.


我能够获得与所有网络接口相关的所有IP地址,但我如何区分它们?

  • 127.xxx.xxx.xxx范围内的任何地址都是"环回"地址.它只对"这个"主机可见.
  • 192.168.xxx.xxx范围内的任何地址都是私有(即本地站点)IP地址.这些保留在组织内使用.这同样适用于10.xxx.xxx.xxx地址,以及172.16.xxx.xxx到172.31.xxx.xxx.
  • 169.254.xxx.xxx范围内的地址是链路本地IP地址.这些保留用于单个网段.
  • 224.xxx.xxx.xxx到239.xxx.xxx.xxx范围内的地址是多播地址.
  • 地址255.255.255.255是广播地址.
  • 其他任何东西都应该是有效的公共点对点IPv4地址.

事实上,InetAddress API提供了测试环回,链接本地,站点本地,多播和广播地址的方法.您可以使用这些来排序您最合适的IP地址.

  • 万一有人好奇,getLocalHost本质上是在服务器的主机名上进行DNS查找。如果它从该查找中获得IP地址,则它将搜索可用的接口以查看哪个接口具有该IP地址,并返回该接口。这意味着getLocalHost将倾向于在“服务器”环境中工作,在该环境中,传出IP是映射到服务器主机名的IP。 (2认同)

Mr.*_*oor 101

import java.net.DatagramSocket;

try(final DatagramSocket socket = new DatagramSocket()){
  socket.connect(InetAddress.getByName("8.8.8.8"), 10002);
  ip = socket.getLocalAddress().getHostAddress();
}
Run Code Online (Sandbox Code Playgroud)

当有多个网络接口时,这种方式很有效.它始终返回首选的出站IP.目标8.8.8.8不需要可访问.

Connect在UDP套接字上具有以下效果:它设置发送/接收的目的地,丢弃来自其他地址的所有数据包,以及 - 我们使用的 - 将套接字转换为"已连接"状态,设置其相应的字段.这包括根据系统的路由表检查到目的地的路由是否存在,并相应地设置本地端点.最后一部分似乎没有正式的文档,但它看起来像是Berkeley套接字API(UDP"连接"状态的副作用)的一个完整特征,它可以在Windows和Linux中跨版本和发行版可靠地工作.

因此,此方法将提供用于连接到指定远程主机的本地地址.没有建立真正的连接,因此指定的远程IP可以无法访问.

  • 它在linux上工作,但在OsX上我得到:"0.0.0.0" (6认同)
  • @trilogy我仍然在OSX上获得0.0.0.0 (4认同)

Vad*_*zim 55

这里发布的测试来自https://issues.apache.org/jira/browse/JCS-40的 IP模糊解决方法代码(InetAddress.getLocalHost()在Linux系统上不明确):

/**
 * Returns an <code>InetAddress</code> object encapsulating what is most likely the machine's LAN IP address.
 * <p/>
 * This method is intended for use as a replacement of JDK method <code>InetAddress.getLocalHost</code>, because
 * that method is ambiguous on Linux systems. Linux systems enumerate the loopback network interface the same
 * way as regular LAN network interfaces, but the JDK <code>InetAddress.getLocalHost</code> method does not
 * specify the algorithm used to select the address returned under such circumstances, and will often return the
 * loopback address, which is not valid for network communication. Details
 * <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4665037">here</a>.
 * <p/>
 * This method will scan all IP addresses on all network interfaces on the host machine to determine the IP address
 * most likely to be the machine's LAN address. If the machine has multiple IP addresses, this method will prefer
 * a site-local IP address (e.g. 192.168.x.x or 10.10.x.x, usually IPv4) if the machine has one (and will return the
 * first site-local address if the machine has more than one), but if the machine does not hold a site-local
 * address, this method will return simply the first non-loopback address found (IPv4 or IPv6).
 * <p/>
 * If this method cannot find a non-loopback address using this selection algorithm, it will fall back to
 * calling and returning the result of JDK method <code>InetAddress.getLocalHost</code>.
 * <p/>
 *
 * @throws UnknownHostException If the LAN address of the machine cannot be found.
 */
private static InetAddress getLocalHostLANAddress() throws UnknownHostException {
    try {
        InetAddress candidateAddress = null;
        // Iterate all NICs (network interface cards)...
        for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();) {
            NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
            // Iterate all IP addresses assigned to each card...
            for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
                InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
                if (!inetAddr.isLoopbackAddress()) {

                    if (inetAddr.isSiteLocalAddress()) {
                        // Found non-loopback site-local address. Return it immediately...
                        return inetAddr;
                    }
                    else if (candidateAddress == null) {
                        // Found non-loopback address, but not necessarily site-local.
                        // Store it as a candidate to be returned if site-local address is not subsequently found...
                        candidateAddress = inetAddr;
                        // Note that we don't repeatedly assign non-loopback non-site-local addresses as candidates,
                        // only the first. For subsequent iterations, candidate will be non-null.
                    }
                }
            }
        }
        if (candidateAddress != null) {
            // We did not find a site-local address, but we found some other non-loopback address.
            // Server might have a non-site-local address assigned to its NIC (or it might be running
            // IPv6 which deprecates the "site-local" concept).
            // Return this non-loopback candidate address...
            return candidateAddress;
        }
        // At this point, we did not find a non-loopback address.
        // Fall back to returning whatever InetAddress.getLocalHost() returns...
        InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
        if (jdkSuppliedAddress == null) {
            throw new UnknownHostException("The JDK InetAddress.getLocalHost() method unexpectedly returned null.");
        }
        return jdkSuppliedAddress;
    }
    catch (Exception e) {
        UnknownHostException unknownHostException = new UnknownHostException("Failed to determine LAN address: " + e);
        unknownHostException.initCause(e);
        throw unknownHostException;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 必须注意的是,如果主机具有多个类似的网络接口,这仍然无法解决问题. (6认同)
  • 下面的答案更好 - /sf/ask/663730581/#38342964 获取用作的本地 IP 地址默认网关的 src (2认同)

Ran*_*Rag 50

您可以使用java的InetAddress类来实现此目的.

InetAddress IP=InetAddress.getLocalHost();
System.out.println("IP of my system is := "+IP.getHostAddress());
Run Code Online (Sandbox Code Playgroud)

我系统的输出= IP of my system is := 10.100.98.228

getHostAddress()返回

返回文本表示中的IP地址字符串.

或者你也可以

InetAddress IP=InetAddress.getLocalHost();
System.out.println(IP.toString());
Run Code Online (Sandbox Code Playgroud)

输出= IP of my system is := RanRag-PC/10.100.98.228

  • 请注意10.xxx是专用地址,表示您的系统位于NAT网络上.在与外界联系时,它将显示为不同的地址.如果您确实需要外部IP地址,则必须联系许多站点中的一个站点,这些站点将向您回复您来自的IP地址.这可能对您有用,也可能没用.在任何情况下,您的系统几乎肯定无法从外部访问. (9认同)
  • 该解决方案不适用于Linux系统。 (2认同)

小智 18

当您在寻找"本地"地址时,您应该注意每台机器不仅有一个网络接口,而且每个接口都有自己的本地地址.这意味着您的机器始终拥有多个"本地"地址.

当您连接到不同的端点时,将自动选择不同的"本地"地址.例如,当您连接到时google.com,您使用的是"外部"本地地址; 但是当你连接到你的时localhost,你的本地地址总是localhost本身的,因为localhost只是一个环回.

下面显示了在与您沟通时如何找到您的本地地址google.com:

Socket socket = new Socket();
socket.connect(new InetSocketAddress("google.com", 80));
System.out.println(socket.getLocalAddress());
Run Code Online (Sandbox Code Playgroud)

  • 在末尾添加socket.close():) (3认同)

nIc*_*cOw 10

编辑1:由于上一个链接,更新的代码不再存在

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

public class GetMyIP {
    public static void main(String[] args) {
        URL url = null;
        BufferedReader in = null;
        String ipAddress = "";
        try {
            url = new URL("http://bot.whatismyipaddress.com");
            in = new BufferedReader(new InputStreamReader(url.openStream()));
            ipAddress = in.readLine().trim();
            /* IF not connected to internet, then
             * the above code will return one empty
             * String, we can check it's length and
             * if length is not greater than zero, 
             * then we can go for LAN IP or Local IP
             * or PRIVATE IP
             */
            if (!(ipAddress.length() > 0)) {
                try {
                    InetAddress ip = InetAddress.getLocalHost();
                    System.out.println((ip.getHostAddress()).trim());
                    ipAddress = (ip.getHostAddress()).trim();
                } catch(Exception exp) {
                    ipAddress = "ERROR";
                }
            }
        } catch (Exception ex) {
            // This try will give the Private IP of the Host.
            try {
                InetAddress ip = InetAddress.getLocalHost();
                System.out.println((ip.getHostAddress()).trim());
                ipAddress = (ip.getHostAddress()).trim();
            } catch(Exception exp) {
                ipAddress = "ERROR";
            }
            //ex.printStackTrace();
        }
        System.out.println("IP Address: " + ipAddress);
    }
}
Run Code Online (Sandbox Code Playgroud)

实际版本:这停止了工作

希望这段代码可以帮助您实现这一目标:

// Method to get the IP Address of the Host.
private String getIP()
{
    // This try will give the Public IP Address of the Host.
    try
    {
        URL url = new URL("http://automation.whatismyip.com/n09230945.asp");
        BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
        String ipAddress = new String();
        ipAddress = (in.readLine()).trim();
        /* IF not connected to internet, then
         * the above code will return one empty
         * String, we can check it's length and
         * if length is not greater than zero, 
         * then we can go for LAN IP or Local IP
         * or PRIVATE IP
         */
        if (!(ipAddress.length() > 0))
        {
            try
            {
                InetAddress ip = InetAddress.getLocalHost();
                System.out.println((ip.getHostAddress()).trim());
                return ((ip.getHostAddress()).trim());
            }
            catch(Exception ex)
            {
                return "ERROR";
            }
        }
        System.out.println("IP Address is : " + ipAddress);

        return (ipAddress);
    }
    catch(Exception e)
    {
        // This try will give the Private IP of the Host.
        try
        {
            InetAddress ip = InetAddress.getLocalHost();
            System.out.println((ip.getHostAddress()).trim());
            return ((ip.getHostAddress()).trim());
        }
        catch(Exception ex)
        {
            return "ERROR";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果我总是连接到互联网,则该解决方案将起作用,但是我不能保证。此外,当系统未连接到Internet时,我需要返回系统的LAN IP地址(如果有),否则返回本地主机。所以对我来说不是一个可行的选择。还有其他办法吗? (2认同)

And*_*wik 10

scala中的示例(在sbt文件中有用):

  import collection.JavaConverters._
  import java.net._

  def getIpAddress: String = {

    val enumeration = NetworkInterface.getNetworkInterfaces.asScala.toSeq

    val ipAddresses = enumeration.flatMap(p =>
      p.getInetAddresses.asScala.toSeq
    )

    val address = ipAddresses.find { address =>
      val host = address.getHostAddress
      host.contains(".") && !address.isLoopbackAddress
    }.getOrElse(InetAddress.getLocalHost)

    address.getHostAddress
  }
Run Code Online (Sandbox Code Playgroud)


Gau*_*tam 6

首先导入课程

import java.net.InetAddress;
Run Code Online (Sandbox Code Playgroud)

在班上

  InetAddress iAddress = InetAddress.getLocalHost();
  String currentIp = iAddress.getHostAddress();
  System.out.println("Current IP address : " +currentIp); //gives only host address
Run Code Online (Sandbox Code Playgroud)

  • 它只给出第一个 IP 地址,即使它不是正在使用的 IP 地址! (2认同)

Ved*_*Ved 5

您可以使用java.net.InetAddressAPI。尝试这个 :

InetAddress.getLocalHost().getHostAddress();
Run Code Online (Sandbox Code Playgroud)

  • 它只会返回127.0.0.1 (3认同)

J.R*_*J.R 5

private static InetAddress getLocalAddress(){
        try {
            Enumeration<NetworkInterface> b = NetworkInterface.getNetworkInterfaces();
            while( b.hasMoreElements()){
                for ( InterfaceAddress f : b.nextElement().getInterfaceAddresses())
                    if ( f.getAddress().isSiteLocalAddress())
                        return f.getAddress();
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return null;
    }
Run Code Online (Sandbox Code Playgroud)