Java网络编程从入门到精通(10):Inet4Address类和Inet6Address类

本文介绍如何使用Java的InetAddress类及其子类Inet4Address和Inet6Address来判断和解析IPv4与IPv6地址,包括通过IP地址长度和特定方法来识别地址类型,并提供示例代码进行演示。

转自:

http://www.blogjava.net/nokiaguy/archive/2009/04/archive/2009/nokiaguy/archive/2009/nokiaguy/archive/2009/05/04/268874.html

为了区分IPv4IPv6地址,Java提供了两个类:Inet4AddressInet6Address,它们都是InetAddress类的子类,这两个类的定义如下:

public  final  class Inet4Address  extends InetAddress
public  final  class Inet6Address  extends InetAddress

这两个类分别按着IPv4IPv6的规则实现了InetAddress类中的public方法。它们所不同的是Inet6Address类比Inet4Address类多了一个方法:isIPv4CompatibleAddress,这个方法用来判断一个IPv6地址是否和IPv4地址兼容。和IPv4兼容的IPv6地址除了最后四个字节有值名,其他的字节都是0,如0:0:0:0:0:0.192.168.18.10::ABCD:FAFA都是和IPv4兼容的IPv6地址。

当使用InetAddress类的四个静态方法创建InetAddress对象后,可以通过getAddress返回的byte数组来判断这个IP地址是IPv4还是IPv6地址(byte数组长度为4就是IPv4地址,byte数组长度为16就是IPv6地址),也可以将instanceof来确定InetAddress对象是它的哪个子类的实例。下面的代码演示了如何判断一个IP地址是IPv4还是IPv6地址:

package mynet;

import java.net.*;

public  class MyIP
{
     public  static  void main(String[] args)  throws Exception
    {
         if (args.length == 0)
             return;
        InetAddress address = InetAddress.getByName(args[0]);
        System.out.println("IP: " + address.getHostAddress());
         switch (address.getAddress().length)
        {
             case 4:
                System.out.println("根据byte数组长度判断这个IP地址是IPv4地址!");
                 break;
             case 16:
                System.out.println("根据byte数组长度判断这个IP地址是IPv6地址!");
                 break;
        }
         if (address  instanceof Inet4Address)
            System.out.println("使用instanceof判断这个IP地址是IPv4地址!");
         else  if (address  instanceof Inet6Address)
            System.out.println("使用instanceof判断这个IP地址是IPv6地址!");
    }
}

测试1

执行如下命令: 

java mynet.MyIP www.youkuaiyun.com

运行结果:

IP: 211.100.26.122
根据byte数组长度判断这个IP地址是IPv4地址!
使用instanceof判断这个IP地址是IPv4地址! 

测试2

执行如下命令:

java mynet.MyIP www.neu6.edu.cn

运行结果

IP: 2001:da8:9000:b255:200:e8ff:feb0:5c5e
根据byte数组长度判断这个IP地址是IPv6地址!
使用instanceof判断这个IP地址是IPv6地址!

<think>我们正在回答用户关于JavaInet4AddressInet6Address区别的问题。根据引用的资料,我们可以总结如下:1.**的继承关系**:-`Inet4Address``Inet6Address`都是`InetAddress`的子。-`Inet4Address`用于表示IPv4地址,而`Inet6Address`用于表示IPv6地址。2.**表示地址型**:-IPv4地址长度为32位(4字节),通常以点分十进制表示(如`192.168.1.1`)。-IPv6地址长度为128位(16字节),通常以冒号分隔的十六进制表示(如`2001:0db8:85a3:0000:0000:8a2e:0370:7334`)。3.**判断地址型的方法**:-根据引用[4],可以通过检查字节数组的长度来判断:-IPv4地址的字节数组长度为4,IPv6为16。-或者使用`instanceof`操作符:```javaif(addressinstanceofInet4Address){//IPv4地址处理}elseif(addressinstanceofInet6Address){//IPv6地址处理}```4.**使用方式**:-通常我们通过`InetAddress`的静态方法(如`getByName()`)获取实例,然后根据实际型进行转换或判断。-示例代码(根据引用[4]修改):```javaInetAddressaddress=InetAddress.getByName("www.example.com");if(address.getAddress().length==4){System.out.println("IPv4地址");}elseif(address.getAddress().length==16){System.out.println("IPv6地址");}```5.**注意事项**:-在同时支持IPv4IPv6的环境中,域名可能解析到多个地址(包括IPv4IPv6)。-通过`InetAddress.getAllByName()`可以获取所有地址。综上所述,`Inet4Address``Inet6Address`的主要区别在于它们所表示的IP地址版本不同,分别对应IPv4IPv6。在实际编程中,我们通常通过`InetAddress`的方法获取地址实例,再根据实际需要判断或转换型。下面生成相关问题:</think> ### JavaInet4AddressInet6Address的区别及用法 #### 一、核心区别对比 | 特性 | Inet4Address | Inet6Address | |--------------|----------------------------------|----------------------------------| | **地址长度** | 32位(4字节) | 128位(16字节) | | **地址格式** | 点分十进制(如`192.168.1.1`) | 冒号分隔十六进制(如`2001:db8::1`) | | **所属协议** | IPv4 | IPv6 | | **继承关系** | `InetAddress`的子 | `InetAddress`的子 | | **典型用法** | 传统网络应用 | 新一代互联网应用 | #### 二、关键差异详解 1. **地址表示能力** - `Inet4Address`:最多支持$2^{32}$个地址(约43亿),使用4字节存储 - `Inet6Address`:支持$2^{128}$个地址(约$3.4 \times 10^{38}$),使用16字节存储,解决IPv4地址耗尽问题[^1] 2. **特殊功能支持** IPv6专属特性(仅`Inet6Address`支持): ```java // 获取IPv6作用域 NetworkInterface scope = inet6Address.getScopedInterface(); // 检查是否链路本地地址 boolean isLinkLocal = inet6Address.isLinkLocalAddress(); ``` 3. **型判断方法** ```java InetAddress address = InetAddress.getByName("example.com"); // 方法1:通过instanceof判断 if (address instanceof Inet4Address) { System.out.println("IPv4地址"); } else if (address instanceof Inet6Address) { System.out.println("IPv6地址"); } // 方法2:通过字节长度判断 byte[] bytes = address.getAddress(); if (bytes.length == 4) { // IPv4 // ... } else if (bytes.length == 16) { // IPv6 // ... } ``` #### 三、使用示例 **获取IP地址对象**: ```java // 创建IPv4地址 Inet4Address ipv4 = (Inet4Address) Inet4Address.getByName("192.168.1.1"); // 创建IPv6地址 Inet6Address ipv6 = (Inet6Address) Inet6Address.getByName("2001:db8:85a3::8a2e:370:7334"); ``` **域名解析(双栈支持)**: ```java InetAddress[] addresses = InetAddress.getAllByName("google.com"); for (InetAddress addr : addresses) { if (addr instanceof Inet4Address) { System.out.println("IPv4: " + addr.getHostAddress()); } else if (addr instanceof Inet6Address) { System.out.println("IPv6: " + addr.getHostAddress()); } } // 输出可能同时包含IPv4IPv6地址 ``` #### 四、注意事项 1. **兼容处理** 当系统启用双栈支持时,域名解析可能返回两种地址型,需做好兼容: ```java // 优先使用IPv4地址 Arrays.stream(addresses) .filter(a -> a instanceof Inet4Address) .findFirst() .orElse(addresses[0]); ``` 2. **文本表示差异** IPv6地址需处理压缩格式(如`::`)可选端口号: ```java String ipv6String = ipv6.getHostAddress(); // 2001:db8::1 ``` 3. **作用域限定** IPv6地址可能关联网络接口: ```java NetworkInterface ni = NetworkInterface.getByName("eth0"); Inet6Address scopedAddr = Inet6Address.getByAddress( "host", ipv6Bytes, ni ); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值