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

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

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

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

我需要客户端注册其PPP IP,如果可用; 否则,局域网IP(如果可用); 否则,它必须注册127.0.0.1,假设它是同一台计算机。

使用代码:

System.out.println(Inet4Address.getLocalHost().getHostAddress());

or

System.out.println(InetAddress.getLocalHost().getHostAddress());

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

EDIT

我正在使用以下代码:

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());
    }
}

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

127.0.0.1
192.168.1.2
192.168.56.1
117.204.44.19

当前回答

通常当我试图找到我的公共IP地址,如cmyip.com或www.iplocation.net,我使用这种方式:

public static String myPublicIp() {

    /*nslookup myip.opendns.com resolver1.opendns.com*/
    String ipAdressDns  = "";
    try {
        String command = "nslookup myip.opendns.com resolver1.opendns.com";
        Process proc = Runtime.getRuntime().exec(command);

        BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));

        String s;
        while ((s = stdInput.readLine()) != null) {
            ipAdressDns  += s + "\n";
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    return ipAdressDns ;
}

其他回答

你可以使用java.net.InetAddress API。 试试这个:

InetAddress.getLocalHost().getHostAddress();

如果您的机器是网络的一部分,那么它将获取您的网络的IP地址

try {
    System.out.println(InetAddress.getLocalHost().getHostAddress());
} catch (UnknownHostException e) {
    e.printStackTrace();
}

你的计算机可以有多个网络接口,每个网络接口有多个inetaddress。如果过滤掉任何本地地址,则提醒的地址是非本地地址,其中可以有一个、没有或多个。

不幸的是,Java中的网络API仍然使用(旧的)枚举而不是迭代器和流,我们可以通过将它们包装为流来进行对抗。所以我们要做的就是

所有网络接口及其地址的流,以及 过滤掉本地的

代码:

private Stream<InetAddress> getNonLocalIpAddresses() throws IOException {
    return enumerationAsStream(NetworkInterface.getNetworkInterfaces())
        .flatMap(networkInterface -> enumerationAsStream(networkInterface.getInetAddresses()))
        .filter(inetAddress -> !inetAddress.isAnyLocalAddress())
        .filter(inetAddress -> !inetAddress.isSiteLocalAddress())
        .filter(inetAddress -> !inetAddress.isLoopbackAddress())
        .filter(inetAddress -> !inetAddress.isLinkLocalAddress());
}

在我的机器上,这目前返回两个IPv6地址。

要获得这些inetaddress中的第一个:

private String getMyIp() throws IOException {
    return getNonLocalIpAddresses()
        .map(InetAddress::getHostAddress)
        .findFirst()
        .orElseThrow(NoSuchElementException::new);
}

将枚举包装为流的方法:

public static <T> Stream<T> enumerationAsStream(Enumeration<T> e) {
    return StreamSupport.stream(
        Spliterators.spliteratorUnknownSize(
            new Iterator<>() {
                public T next() { return e.nextElement();  }
                public boolean hasNext() { return e.hasMoreElements(); }
            }, Spliterator.ORDERED), false);
}

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
  }

你可以使用java的InetAddress类来实现这个目的。

InetAddress IP=InetAddress.getLocalHost();
System.out.println("IP of my system is := "+IP.getHostAddress());

my system = IP的输出是:= 10.100.98.228

getHostAddress()返回

以文本形式返回IP地址字符串。

或者你也可以这样做

InetAddress IP=InetAddress.getLocalHost();
System.out.println(IP.toString());

我的系统Output = IP为:= RanRag-PC/10.100.98.228