目前ipv6的應用越來越廣泛,慢慢將變成強制的標準,做網路應用開發的,在未來會越來越的要開始支援ipv6,但是ipv6肯定不是一下子就可以大範圍應用的,必然有一段時間ipv4與ipv6共存,要做到對ipv4和ipv6的同時支援。
關於如何讓程式支援ipv6 可以參考
示例**見:
這個文章只講如何相容ipv4和ipv6
如果使用asio這樣成熟的網路庫,就無需再看此文,asio已經將底層的差別遮蔽。
這裡只討論從socket層面自已開發網路庫時,支援ipv4 和ipv6會遇到的情況。
使用這樣的結構體既可以表示ipv4的位址,又可以表示ipv6位址
struct myaddrinfo;
};
union聯合體中的三個結構體 大概如下所示(與標準有一些區別,主要方便理解): 源自
/* structure describing a generic socket address. */
struct sockaddr
;/* structure describing an internet socket address. */
struct sockaddr_in
;/* ditto, for ipv6. */
struct sockaddr_in6
;
此處由於windows平台下和linux平台下對sockaddr_in6的定義有些區別,所以需要盡量使用兩個平台下定義相同的變數,避免使用系統中定義名稱的變數。
獲取ip位址
//返回ipv4 位址
static uint32_t get_ipv4(const myaddrinfo &addr)
//返回ipv6 位址
static in6_addr get_ipv6(const myaddrinfo &addr)
ip位址字串
//返回ipv4或v6位址字串
static inline std::string get_ipstr(const myaddrinfo &addr)
else if (addr.ai_family == af_inet6)
else return std::string("");
}
獲取埠號
static inline uint16_t get_port(const myaddrinfo &addr)
else if (addr.ai_family == af_inet6)
else return 0;
}
如果程式監聽的是 ::0 位址,即ipv6位址, 對於同時具有ipv4位址和 ipv6位址的 雙棧伺服器來講, 會同時監聽ipv4和ipv6協議棧上的某個埠,客戶端連線伺服器的時候,如果使用的是ipv4連線的,顯示出的結果是 ::ff:192.168.3.8這樣經過對映的ipv6的位址。
如果要判斷是否是ipv4對映的位址,可以用如下辦法
//是否是v4對映的v6位址
; static const prefix prefix;
static const int prefix_size = 12;
// [00:00:00:00:00 :00:00:00:00:00 :ff:ff] 共12個位元組
if (memcmp(&prefix, &(addr.addr6.sin6_addr), prefix_size) == 0)
return true;
else
return false;
} //ipv4位址,對映前的位址 (網路位元組序)
static uint32_t get_ipv4_inv6(const myaddrinfo &addr)
更詳細的例子可以參考:
參考:
nginx 的實現
校驗IPv4和IPv6位址和URL位址
function validateip obj obj val dialogtop alert alert warning return false 呼叫 onblur validateip this function addfilterip images delete.png onclick de...
IPv4與IPv6位址格式詳解
ipv4位址是類似 a.b.c.d 的格式,它是32位,用 分成四段,用10進製表示 ipv6位址類似 x x x x x x x x的格式,它是128位的,用 分成8段,每個x是乙個16進製制數 16 2 4 可見,ipv6位址空間相對於ipv4位址有了極大的擴充 ipv6 位址的長度為 128 ...
IPv6知識概述 IPv6位址
首選格式 x x x x x x x x x表示乙個4位十六進製制數 典型的例子如下所示 2000 0000 0000 0000 0001 2345 6789 abcd ipv6位址每段中的前導0是可以去掉的,但是至少要保證每一段有乙個數字。將不必要的前導0去掉後,上述位址可以表示為 2000 0 ...