首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 網路程式設計精通指南(8):getAddress() — 獲取 byte[] 形式 IP 地址與符號位處理

     編輯:Java 相關知識

InetAddress.getAddress() 返回 byte[] 形式的 IP 地址(IPv4 為 4 字節,IPv6 為 16 字節),與返回字符串的 getHostAddress() 互補。本文重點講解 Java byte 有符號特性導致的負數顯示問題及正確轉換方法。

方法簽名

public byte[] getAddress()

符號位陷阱

Java byte 為有符號 8 位整數,範圍 -128 ~ 127。IP 地址字節值 > 127 時,直接打印會顯示負數:

InetAddress addr = InetAddress.getByName("www.csdn.net"); // 211.100.26.122
byte[] ip = addr.getAddress();
for (byte b : ip) System.out.print(b + " "); // 輸出: -45 100 26 122

第一字節 211 (>127) 顯示為 -45 (211 - 256)。

正確轉換為無符號整數 (0~255)

方法 1:位運算 & 0xFF (推薦,高效)

for (byte b : ip) {
    int unsigned = b & 0xFF; // 將負數補碼轉為正數
    System.out.print(unsigned + " ");
}
// 輸出: 211 100 26 122

方法 2:條件判斷 (易讀,稍慢)

for (byte b : ip) {
    int unsigned = (b < 0) ? b + 256 : b;
    System.out.print(unsigned + " ");
}

方法 3:Byte.toUnsignedInt() (Java 8+)

for (byte b : ip) {
    System.out.print(Byte.toUnsignedInt(b) + " ");
}

完整工具類:IP 地址標準化輸出

public class IpAddressUtils {
    public static String toDottedString(byte[] ip) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < ip.length; i++) {
            if (i > 0) sb.append(ip.length == 4 ? "." : ":");
            sb.append(ip[i] & 0xFF);
        }
        return sb.toString();
    }

    public static String toDottedString(InetAddress addr) {
        return toDottedString(addr.getAddress());
    }

    // IPv6 簡寫邏輯可在此擴展 (壓縮連續 0 段)
}

使用示例

InetAddress ipv4 = InetAddress.getByName("211.100.26.122");
InetAddress ipv6 = InetAddress.getByName("2001:da8:9000:b255:200:e8ff:feb0:5c5e");

System.out.println("IPv4: " + IpAddressUtils.toDottedString(ipv4)); // 211.100.26.122
System.out.println("IPv6: " + IpAddressUtils.toDottedString(ipv6)); // 2001:da8:9000:b255:200:e8ff:feb0:5c5e (未壓縮)

// 獲取單字節值 (如提取 IPv4 最後一段)
int lastOctet = ipv4.getAddress()[3] & 0xFF; // 122

應用場景

  • 序列化 IP 地址至字節流/數據庫 (BINARY(4)/BINARY(16))。
  • 位運算計算網段、掩碼、廣播地址 (需無符號值)。
  • 自定義協議中編碼/解碼 IP 字段。
  • 與 C/C++、Go 等無符號 byte 語言交互時的數據對齊。

總結

getAddress() 返回原始字節數組,必須配合 & 0xFF 或 Byte.toUnsignedInt() 處理符號位,才能獲得正確的 0~255 數值。切勿直接打印或運算 byte 值,否則會導致邏輯錯誤 (如 211 變 -45 破壞網段計算)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved