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

现在,所有节点都创建了一个套接字,将目标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

当前回答

首先导入类

import java.net.InetAddress;

在课堂上

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

其他回答

因为我的系统(像许多其他系统一样)有各种网络接口。inetaddress . getlocalhost()或Inet4Address.getLocalHost()只是返回一个我不需要的网络接口。 因此,我不得不使用这种幼稚的方法。

InetAddress[] allAddresses = Inet4Address.getAllByName("YourComputerHostName");
        InetAddress desiredAddress;
        //In order to find the desired Ip to be routed by other modules (WiFi adapter)
        for (InetAddress address :
                allAddresses) {
            if (address.getHostAddress().startsWith("192.168.2")) {
                desiredAddress = address;
            }
        }
// Use the desired address for whatever purpose.

只是要注意,在这种方法中,我已经知道我想要的IP地址在192.168.2子网中。

你可以使用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

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

InetAddress.getLocalHost().getHostAddress();

你的计算机可以有多个网络接口,每个网络接口有多个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);
}

在寻找“本地”地址时,应该注意到每台机器不仅只有一个网络接口,而且每个接口可以有自己的本地地址。这意味着您的机器总是拥有几个“本地”地址。

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

下面是当你与google.com通信时如何找到你的本地地址:

Socket socket = new Socket();
socket.connect(new InetSocketAddress("google.com", 80));
System.out.println(socket.getLocalAddress());
socket.close();