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

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

其他回答

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

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

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

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

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

一个Kotlin的例子,至少在Windows上可以工作,即使我的VPN是打开的。 (当VPN打开时,其他方法似乎失败了) 它只需要查找一次计算机的IP地址。从那时起,始终可以从存储的适配器信息中找到IP地址。

import java.net.NetworkInterface
import java.util.prefs.Preferences

class WindowsIP {
    companion object {
        val prefs = Preferences.userNodeForPackage(this::class.java)  //Get the current IP address for the wifi adapter whose information
        // has been stored by calling findWifiAdapter(currentIp) with the known current IP (from wifi properties or whatever)
        fun getIpAddress(): String {
            val wlanName = prefs.get("WlanName", "")
            val wlanDisplName = prefs.get("WlanDisplName", "")
            val addrCnt = prefs.getInt("wlanAddrCount", 0)
            val nis = NetworkInterface.getNetworkInterfaces()
            for (ni in nis) {
                if (ni.name == wlanName && ni.displayName == wlanDisplName) {
                    var count = 0
                    for (addr in ni.inetAddresses) {
                        if (count++ == addrCnt) {
                            return addr.hostAddress
                        }
                    }
                }
            }
            return "Unknown. Call findWifiAdapter() with current IP address"
        }

        fun findWifiAdapter(currentIP: String) {  //Find the wifi adapter using the current IP address and store the information
                val nis = NetworkInterface.getNetworkInterfaces()
                for(ni in nis) {
                    var count = 0;
                    for(adr in ni.inetAddresses) {
                        if(adr.hostAddress == currentIP) {
                            prefs.put("WlanName", ni.name)
                            prefs.put("WlanDisplName", ni.displayName)
                            prefs.putInt("wlanAddrCount", count)  //Probably always zero?
                        }
                        ++count
                    }
                }
        }
    }
}

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

import java.net.InetAddress;

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

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

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