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

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

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

其他回答

通常当我试图找到我的公共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 ;
}

使用InetAddress.getLocalHost()获取本地地址

import java.net.InetAddress;

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

一个相当简单的方法似乎很有效……

String getPublicIPv4() throws UnknownHostException, SocketException{
    Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
    String ipToReturn = null;
    while(e.hasMoreElements())
    {
        NetworkInterface n = (NetworkInterface) e.nextElement();
        Enumeration<InetAddress> ee = n.getInetAddresses();
        while (ee.hasMoreElements())
        {
            InetAddress i = (InetAddress) ee.nextElement();
            String currentAddress = i.getHostAddress();
            logger.trace("IP address "+currentAddress+ " found");
            if(!i.isSiteLocalAddress()&&!i.isLoopbackAddress() && validate(currentAddress)){
                ipToReturn = currentAddress;    
            }else{
                System.out.println("Address not validated as public IPv4");
            }

        }
    }

    return ipToReturn;
}

private static final Pattern IPv4RegexPattern = Pattern.compile(
        "^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");

public static boolean validate(final String ip) {
    return IPv4RegexPattern.matcher(ip).matches();
}

你的计算机可以有多个网络接口,每个网络接口有多个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);
}
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;

public class IpAddress {

NetworkInterface ifcfg;
Enumeration<InetAddress> addresses;
String address;

public String getIpAddress(String host) {
    try {
        ifcfg = NetworkInterface.getByName(host);
        addresses = ifcfg.getInetAddresses();
        while (addresses.hasMoreElements()) {
            address = addresses.nextElement().toString();
            address = address.replace("/", "");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return ifcfg.toString();
}
}