隨著網際網路的快速發展,IPv4 位址耗盡已成定局,IPv6 成為必然趨勢。許多開發者在維護既有網路程式碼時,面臨如何將原本基於 IPv4 架構的程式平滑遷移至 IPv6 的挑戰。本文整理自 Beej's Guide to Network Programming 系列教學,詳細說明從 IPv4 移植到 IPv6 所需的 12 個關鍵修改點,助你快速實現雙協議棧相容。
最重要的原則是:拋棄硬編碼,擁抱 getaddrinfo()。這個函數能自動處理 DNS 解析、服務名稱查詢,並填充適當的位址結構,讓你的程式碼同時支援 IPv4 與 IPv6,無需在編譯時決定協議版本。
替換舊有的手動封裝 sockaddr 結構方式,使用 getaddrinfo() 取得 struct sockaddr 資訊,這是實現 IP 版本無關性的基石。
檢查程式碼中所有寫死的 IPv4 專用常數,改用對應的通用函數或巨集替換。
AF_INET → AF_INET6PF_INET → PF_INET6將 INADDR_ANY 替換為 in6addr_any。宣告 struct in6_addr 時,也可使用 IN6ADDR_ANY_INIT 初始化:
struct sockaddr_in sa;
struct sockaddr_in6 sa6;
sa.sin_addr.s_addr = INADDR_ANY; // IPv4 通配位址
sa6.sin6_addr = in6addr_any; // IPv6 通配位址
// 或直接初始化 in6_addr 結構
struct in6_addr ia6 = IN6ADDR_ANY_INIT;
struct sockaddr_in → struct sockaddr_in6(注意 IPv6 結構無 sin6_zero 欄位)struct in_addr → struct in6_addrinet_pton() 取代 inet_aton() 和 inet_addr()inet_ntop() 取代 inet_ntoa()新函數支援 IPv4 與 IPv6 兩種格式,參數中需指定位址家族(AF_INET 或 AF_INET6)。
getaddrinfo() 取代 gethostbyname()getnameinfo() 取代 gethostbyaddr()(舊函數雖支援 IPv6 但已過時)IPv6 不使用傳統廣播(INADDR_BROADCAST),改用多播機制。需重新設計應用層協議以適應多播群組管理。
遷移到 IPv6 並非單純的「搜尋取代」,而是架構層面的現代化。核心在於:以 getaddrinfo() 為中心,消除所有對特定 IP 版本的假設。完成上述 12 項修改後,你的網路程式將具備真正的雙協議棧能力,為未來網路環境奠定堅實基礎。