Java中InetAddress的使用(二):获取本机IP地址的正确姿势【享学Java】(下)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: Java中InetAddress的使用(二):获取本机IP地址的正确姿势【享学Java】(下)


复杂情况(通用,推荐的方案)


它是一种通用方案,推荐使用在实际的代码中。


public static void main(String[] args) throws UnknownHostException {
    InetAddress localHost = InetAddress.getLocalHost();
    System.out.println(localHost.getHostAddress());
    System.out.println("----------------下面才是正确的获取方式----------------");
    localHost = getLocalHostExactAddress();
    System.out.println(localHost.getHostAddress());
    // System.out.println(localHost.getHostName());
}
public static InetAddress getLocalHostExactAddress() {
    try {
        InetAddress candidateAddress = null;
        Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
        while (networkInterfaces.hasMoreElements()) {
            NetworkInterface iface = networkInterfaces.nextElement();
            // 该网卡接口下的ip会有多个,也需要一个个的遍历,找到自己所需要的
            for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements(); ) {
                InetAddress inetAddr = inetAddrs.nextElement();
                // 排除loopback回环类型地址(不管是IPv4还是IPv6 只要是回环地址都会返回true)
                if (!inetAddr.isLoopbackAddress()) {
                    if (inetAddr.isSiteLocalAddress()) {
                        // 如果是site-local地址,就是它了 就是我们要找的
                        // ~~~~~~~~~~~~~绝大部分情况下都会在此处返回你的ip地址值~~~~~~~~~~~~~
                        return inetAddr;
                    }
                    // 若不是site-local地址 那就记录下该地址当作候选
                    if (candidateAddress == null) {
                        candidateAddress = inetAddr;
                    }
                }
            }
        }
        // 如果出去loopback回环地之外无其它地址了,那就回退到原始方案吧
        return candidateAddress == null ? InetAddress.getLocalHost() : candidateAddress;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}


在windows运行输出(即使你开了vpn都木有关系的哦):

2.0.2.81
----------------下面才是正确的获取方式----------------
192.168.199.175



在Linux下运行输出:

127.0.0.1
----------------下面才是正确的获取方式----------------
10.102.11.29


可以看到通过这种方式获取本机IP,不管是windows or Linux,亦不管是开启了vpn与否,最终均能得到正确的结果。


最后最为辅助材料,介绍下InetAddress的其它方法们。


InetAddress的其它实例方法们介绍


//获取主机名
public String getHostName();
//获取主机名(每次方法都解析DNS去获取主机名,而不从缓存中获取)
public String getCanonicalHostName();
//获取以字节数组形式的ip地址。
public byte[] getAddress();
//获取点分四段式ip。
public String getHostAddress();
//可以根据指定timeout时间内测试网络是否可达,是否可以建立连接。
public boolean isReachable(int timeout);
//可以指定从本机那个网卡、生存时间ttl 和指定时间来测试网络是否可达。
public boolean isReachable(NetworkInterface netif, int ttl, int timeout);
// 当IP地址是广播地址(MulticastAddress)时返回true,否则返回false。
// 通过广播地址可以向网络中的所有计算机发送信息,而不是只向一台特定的计算机发送信息。
// IPv4的广播地址的范围是224.0.0.0 ~ 239.255.255.255
// IPv6的广播地址第一个字节是FF 其他的字节可以是任意值。
public boolean isMulticastAddress();
// 当IP地址是通配符地址时返回true,否则返回false。
// IPv4的通配符地址是0.0.0.0
// IPv6的通配符地址是0:0:0:0:0:0:0:0,也可以简写成::。
public boolean isAnyLocalAddress();
// 当IP地址是loopback地址时返回true,否则返回false。loopback地址就是代表本机的IP地址。
// IPv4的loopback地址的范围是127.0.0.0 ~ 127.255.255.255,也就是说,只要第一个字节是127,就是lookback地址。
// IPv6的loopback地址是0:0:0:0:0:0:0:1,也可以简写成::1
public boolean isLoopbackAddress();
// 当IP地址是本地连接地址(LinkLocalAddress)时返回true,否则返回false。
// IPv4的本地连接地址的范围是169.254.0.0 ~ 169.254.255.255。
// IPv6的本地连接地址的前12位是FE8,其他的位可以是任意取值,如FE88::和FE80::ABCD::都是本地连接地址。
public boolean isLinkLocalAddress();
// 当IP地址是地区本地地址(SiteLocalAddress)时返回true,否则返回false。(是不是内网ip)
// IPv4的地址本地地址分为三段:10.0.0.0 ~ 10.255.255.255、172.16.0.0 ~ 172.31.255.255、192.168.0.0 ~ 192.168.255.255
// (企业内部或个人内部的局域网内部的ip都应该在此三个网段内 因为内网用ipv4足够)
// IPv6的地区本地地址的前12位是FEC,其他的位可以是任意取值,如FED0:: 和 FEF1:: 都是地区本地地址。
public boolean isSiteLocalAddress();
// 当IP地址是全球范围的广播地址时返回true,否则返回false。全球范围的广播地址可以向Internet中的所有的计算机发送信息。
// IPv4的广播地址除了224.0.0.0和第一个字节是239的IP地址都是全球范围的广播地址
// IPv6的全球范围的广播地址中第一个字节是FF,第二个字节的范围是0E ~ FE,其他的字节可以是任意值,如FFBE::、FF0E::都是全球范围的广播地址。
public boolean isMCGlobal();
// 当IP地址是本地接口广播地址时返回true,否则返回false。
// 本地接口广播地址不能将广播信息发送到产生广播信息的网络接口,即使是同一台计算机的另一个网络接口也不行。
// 所有的IPv4广播地址都不是本地接口广播地址。IPv6的本地接口广播地址的第一个字节是FF,第二个节字的范围是01 ~ F1,
// 其他的字节可以是任意值,如FFB1::、FF01:A123::都是本地接口广播地址。
public boolean isMCNodeLocal();
// 当IP地址是子网广播地址时返回true,否则返回false。
// IPv4的子网广播地址的范围是224.0.0.0 ~ 224.0.0.255。
// IPv6的子网广播地址的第一个字节是FF,第二个字节的范围是02 ~ F2,其他的字节可以是任意值,如FFB2:: 和 FF02:ABCD:: 都是子网广播地址。
public boolean isMCLinkLocal();
// 当IP地址是站点范围的广播地址时返回true,否则返回false。 
// 使用站点范围的广播地址,可以向站点范围内的计算机发送广播信息。
// IPv4的站点范围广播地址的范围是239.255.0.0 ~ 239.255.255.255,如239.255.1.1、239.255.0.0都是站点范围的广播地址。
// IPv6的站点范围广播地址的第一个字节是FF,第二个字节的范围是05 ~ F5,其他的字节可以是任意值,如FF05:: 和 FF45:: 都是站点范围的广播地址。
public boolean isMCSiteLocal();
// 当IP地址是组织范围的广播地址时返回ture,否则返回false。
// 使用组织范围广播地址可以向公司或企业内部的所有的计算机发送广播信息。
// IPv4的组织范围广播地址的第一个字节是239,第二个字节不小于192,第三个字节不大于195,如239.193.100.200、239.192.195.0都是组织范围广播地址。
// IPv6的组织范围广播地址的第一个字节是FF,第二个字节的范围是08 ~ F8,其他的字节可以是任意值,如FF08:: 和 FF48::都是组织范围的广播地址。
public boolean isMCOrgLocal();



总结


关于InetAddress的所有内容就介绍到这,相信经过此两篇内容的讲解后,你对Java处理域名解析,以及获取本地IP地址时将不会再胆怯,干吧。另外,其实上Java该有更高级的功能:


  • 自己指定DNS地址,形如这样:


/

// 这么一来我们的hostName域名都将交给`114.114.114.114`去帮我们完成解析
System.setProperty("sun.net.spi.nameservice.nameservers", "114.114.114.114");


自己指定DNS服务的提供者:

// 若你没指定此key,那就是default。默认就会使用系统自带的DNS
// `dns,sun`的意思是:会使用`sun.net.spi.nameservice.nameservers`配置指定的DNS来解析
System.setProperty("sun.net.spi.nameservice.provider.1", "dns,sun");


这些内容几乎很少会涉及到,因此本文并没必要展开。

相关文章
|
2月前
|
Java
Java开发实现图片URL地址检验,如何编码?
【10月更文挑战第14天】Java开发实现图片URL地址检验,如何编码?
77 4
|
2月前
|
Web App开发 Java
使用java操作浏览器的工具selenium-java和webdriver下载地址
【10月更文挑战第12天】Selenium-java依赖包用于自动化Web测试,版本为3.141.59。ChromeDriver和EdgeDriver分别用于控制Chrome和Edge浏览器,需确保版本与浏览器匹配。示例代码展示了如何使用Selenium-java模拟登录CSDN,包括设置驱动路径、添加Cookies和获取页面源码。
|
6月前
|
网络协议 安全 Java
Java网络编程入门涉及TCP/IP协议理解与Socket通信。
【6月更文挑战第21天】Java网络编程入门涉及TCP/IP协议理解与Socket通信。TCP/IP协议包括应用层、传输层、网络层和数据链路层。使用Java的`ServerSocket`和`Socket`类,服务器监听端口,接受客户端连接,而客户端连接指定服务器并交换数据。基础示例展示如何创建服务器和发送消息。进阶可涉及多线程、NIO和安全传输。学习这些基础知识能助你构建网络应用。
52 1
|
29天前
|
Java Spring
JAVA获取重定向地址URL的两种方法
【10月更文挑战第17天】本文介绍了两种在Java中获取HTTP响应头中的Location字段的方法:一种是使用HttpURLConnection,另一种是使用Spring的RestTemplate。通过设置连接超时和禁用自动重定向,确保请求按预期执行。此外,还提供了一个自定义的`NoRedirectSimpleClientHttpRequestFactory`类,用于禁用RestTemplate的自动重定向功能。
|
7月前
|
网络协议 Java
Java的Socket编程:TCP/IP与UDP深入探索
Java的Socket编程:TCP/IP与UDP深入探索
109 0
|
6月前
|
网络协议 Java 程序员
TCP/IP协议栈是网络通信基础,Java的`java.net`包提供工具,使开发者能利用TCP/IP创建网络应用
【6月更文挑战第23天】 **TCP/IP协议栈是网络通信基础,它包含应用层(HTTP, FTP等)、传输层(TCP, UDP)、网络层(IP)、数据链路层(帧, MAC地址)和物理层(硬件信号)。Java的`java.net`包提供工具,使开发者能利用TCP/IP创建网络应用,如Socket和ServerSocket用于客户端和服务器通信。**
55 3
|
6月前
|
Java Apache Maven
蓝易云 - java判断ip是否为指定网段
在这个例子中,我们首先创建了一个 `SubnetUtils`对象,它表示一个子网。然后,我们使用 `isInRange`方法来检查指定的IP地址是否在这个子网内。如果IP地址在子网内,`isInRange`方法将返回 `true`,否则返回 `false`。
113 3
|
5月前
|
Java Redis 数据安全/隐私保护
Redis13的Java客户端-Jedis快速入门,建立连接的写法,ip地址,设置密码密码,选择库的写法
Redis13的Java客户端-Jedis快速入门,建立连接的写法,ip地址,设置密码密码,选择库的写法
|
6月前
|
数据采集 Java 数据安全/隐私保护
使用Java进行网络采集:代理IP与参数传递详解
Java参数传递是按值传递,包括对象引用的值。当传递对象时,方法内部修改对象内容会影响原始对象,但不能改变原始引用。示例展示了如何在爬虫代理中使用此机制,通过`ProxySettings`类传递代理信息,方法内可访问但不能更改原始对象。理解这一机制对编写高效无错的Java代码至关重要。
使用Java进行网络采集:代理IP与参数传递详解
|
Java 应用服务中间件 nginx