InetAddress.getByAddress(byte[] arr)源码解析
2017-05-31 22:54
567 查看
以下代码可以获取到192.168.1.3对应的主机:
参数接收的是一个byte数组,我们都知道,byte数组的范围是-128~127,那么以上代码强转成byte为什么不会溢出,还可以正确获取到对应的主机呢?
以下是getByAddress方法的源码:
以IPv4为例,以上代码返回了:
到这里我们可能还存有一个疑问,IP的最高8位也可能是11111111,那最后拼接起来的int类型IP值是不是也会溢出呢?
我们通过getHostAdress方法获取到的IP地址却是正常的:
先看看getAdress()是怎么写的:
可以看出他是将int类型IP地址按照位运算转成了byte数组(java的API底层位运算是很常见的,提高了代码的执行效率)
最终是用到了以上numericToTextFormat(byte[] src)这个静态方法,仍然是位运算,只不过这里位运算之后自动提升为了int类型,所以即便是位运算之后结果是11111111,也不会溢出。
InetAddress ia = InetAddress.getByAddress(new byte[] { (byte) 192,(byte) 168, 1, 3 });
参数接收的是一个byte数组,我们都知道,byte数组的范围是-128~127,那么以上代码强转成byte为什么不会溢出,还可以正确获取到对应的主机呢?
以下是getByAddress方法的源码:
public static InetAddress getByAddress(byte[] addr) throws UnknownHostException { return getByAddress(null, addr); } public static InetAddress getByAddress(String host, byte[] addr) throws UnknownHostException { return getByAddress(host, addr, -1 /* scopeId */); } // Do not delete. Called from native code. private static InetAddress getByAddress(String host, byte[] addr, int scopeId) throws UnknownHostException { if (host != null && host.length() > 0 && host.charAt(0) == '[') { if (host.charAt(host.length()-1) == ']') { host = host.substring(1, host.length() -1); } } if (addr != null) { if (addr.length == Inet4Address.INADDRSZ) { //IPv4是长度为4个字节的byte数组 return new Inet4Address(host, addr); } else if (addr.length == Inet6Address.INADDRSZ) { //IPv6是长度为16个字节的byte数组 byte[] newAddr = IPAddressUtil.convertFromIPv4MappedAddress(addr); if (newAddr != null) { return new Inet4Address(host, newAddr); } else { return new Inet6Address(host, addr, scopeId); } } } throw new UnknownHostException("addr is of illegal length"); }
以IPv4为例,以上代码返回了:
return new Inet4Address(host, addr);
Inet4Address(String hostName, byte addr[]) { holder().hostName = hostName; holder().family = AF_INET; if (addr != null) { //看到这里就应该都明白了,底层用的是位运算,将4个字节直接按位运算转成了int类型,所以不存在溢出一说 if (addr.length == INADDRSZ) { int address = addr[3] & 0xFF; address |= ((addr[2] << 8) & 0xFF00); address |= ((addr[1] << 16) & 0xFF0000); address |= ((addr[0] << 24) & 0xFF000000); holder().address = address; } } }
到这里我们可能还存有一个疑问,IP的最高8位也可能是11111111,那最后拼接起来的int类型IP值是不是也会溢出呢?
我们通过getHostAdress方法获取到的IP地址却是正常的:
public String getHostAddress() { return numericToTextFormat(getAddress()); }
先看看getAdress()是怎么写的:
public byte[] getAddress() { int address = holder().getAddress(); byte[] addr = new byte[INADDRSZ]; addr[0] = (byte) ((address >>> 24) & 0xFF); addr[1] = (byte) ((address >>> 16) & 0xFF); addr[2] = (byte) ((address >>> 8) & 0xFF); addr[3] = (byte) (address & 0xFF); return addr; }
可以看出他是将int类型IP地址按照位运算转成了byte数组(java的API底层位运算是很常见的,提高了代码的执行效率)
static String numericToTextFormat(byte[] src) { return (src[0] & 0xff) + "." + (src[1] & 0xff) + "." + (src[2] & 0xff) + "." + (src[3] & 0xff); }
最终是用到了以上numericToTextFormat(byte[] src)这个静态方法,仍然是位运算,只不过这里位运算之后自动提升为了int类型,所以即便是位运算之后结果是11111111,也不会溢出。
相关文章推荐
- Java InetAddress.getByAddress()的使用
- Java InetAddress.getByAddress()的使用
- Java InetAddress.getByAddress()的使用
- netty5.0源码解析 ByteBuf和相关辅助类
- Get function name by address in Linux
- Dom4j递归解析XML实现JS的getElementsByName类似方法
- 关于thinkphp 中 使用 token_get_all() 源码解析
- get register by address instead of name
- iOS crash reports: get symbol by address using atos
- InetAddress.getLocalHost() java.net.UnknownHostException 异常
- jsopu getElementsByClass 遇到空格无法解析的解决办法
- InetAddress与String类型的转换,byte[]型与String型转换,编码解码
- Dom4j递归解析XML实现JS的getElementsByName类似方法
- 八.jQuery源码解析之get()
- C3P0在Linux下的Failed to get local InetAddress for VMID解决方法
- InetAddress.getLocalHost().getHostAddress(); 127.0.0.1
- 解析Delphi中的LoadLibrary,GetProcAddress,FreeLibrary
- GetByteArrayElements和ReleaseByteArrayElements
- Blackboard problem: InetAddress.getLocalHost always returns "localhost"
- InetAddress.getLocalHost()详解