[转] JAVA从本机获取IP地址

[From] https://www.cnblogs.com/xiaoBlog2016/p/7076230.html

 

论述:

  此篇博客是在工作的时候,需要获得当前网络下面正确的ip地址,在网上查阅很多博客,网上一个比较普遍的说法是通过InetAddress.getLocalHost().getHostAddress()获取,但只能够获取简单网络环境下的Ip地址,则忽略IP地址在现在的网络环境更加复杂,比如有Lan,WIFI,蓝牙热点,虚拟机网卡...
即存在很多的网络接口(network interfaces),每个网络接口就包含一个IP地址,并不是所有的IP地址能被外部或局域网访问,比如说虚拟机网卡地址等等。
也就是说InetAddress.getLocalHost().getHostAddress()的IP不一定是正确的IP。因此,公司的大神,自己编写测试,并写成博客:http://www.cnblogs.com/starcrm/p/7071227.html;而此篇博客只是在此前提下整理而来

1.明确当前网络的一些规则:

  1.1、127.xxx.xxx.xxx 属于"loopback" 地址,即只能你自己的本机可见,就是本机地址,比较常见的有127.0.0.1;
  1.2、192.168.xxx.xxx 属于private 私有地址(site local address),属于本地组织内部访问,只能在本地局域网可见。同样10.xxx.xxx.xxx、从172.16.xxx.xxx 到 172.31.xxx.xxx都是私有地址,也是属于组织内部访问;

  1.3、169.254.xxx.xxx 属于连接本地地址(link local IP),在单独网段可用

  1.4、从224.xxx.xxx.xxx 到 239.xxx.xxx.xxx 属于组播地址

  1.5、比较特殊的255.255.255.255 属于广播地址

  1.6、除此之外的地址就是点对点的可用的公开IPv4地址

2.简单情况下获得ip地址:

        首先,当你在"百度"或者"bing"中搜索"JAVA获取本机ip地址";一般情况下,我们搜索到的文章或者博客,只能在单一情况下准确获取本机IP地址。例如:例如以下几种情况,即可在下面的博客中获取:

  2.1:只使用WIFI情况;
  2.2:只使用网线的情况

  网址:http://www.cnblogs.com/zrui-xyu/p/5039551.html

3.获取复杂网络环境下的Ip地址

  源码如下所示:

获得当前网络输口的ip地址

public InetAddress getLocalHostLANAddress() throws Exception {
    try {
        InetAddress candidateAddress = null;
        // 遍历所有的网络接口
        for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements(); ) {
            NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
            // 在所有的接口下再遍历IP
            for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements(); ) {
                InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
                if (!inetAddr.isLoopbackAddress()) {// 排除loopback类型地址
                    if (inetAddr.isSiteLocalAddress()) {
                        // 如果是site-local地址,就是它了
                        return inetAddr;
                    } else if (candidateAddress == null) {
                        // site-local类型的地址未被发现,先记录候选地址
                        candidateAddress = inetAddr;
                    }
                }
            }
        }
        if (candidateAddress != null) {
            return candidateAddress;
        }
        // 如果没有发现 non-loopback地址.只能用最次选的方案
        InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
        return jdkSuppliedAddress;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
posted @ 2018-06-19 19:09  Pekkle  阅读(1687)  评论(0编辑  收藏  举报