我有一個UDP服務器必須在IPV4和IPV6地址上爲客戶端服務。我創建了一個IPV6套接字來爲IPV4和IPV6客戶端提供服務。
服務器在第一次通信時存儲客戶端的IP地址。如果它是IPV4客戶端,則它存儲爲IPV4地址,如果它是IPV6客戶端,則服務器將存儲爲IPV6地址。對於將來的所有通信,它會檢查存儲器是否已知(存儲)該客戶端,然後進行相應的處理。爲了比較客戶端地址和存儲地址,我根據家庭類型(AF_INET和AF_INET6)執行了一個memcmp。
與IPV6客戶端通信時,系統正常工作,但在與IPV4客戶端通信時,系統表現得好像從來不知道客戶端一樣。在調試過程中,我發現由於IPV6是Socket Type,因此IPV4客戶端的IP地址被作爲IPV6映射的IPV4地址接收,而IPV4地址族被設置爲IPV6。爲了解決這個問題,我需要比較IPV4存儲地址和IPV6映射地址。爲此,我使用IPV4結構的sin_addr.s_addr和IPV6結構的sin6_addr.in6_u.u6_addr32。請找到下面的代碼片段。比較IPV4套接字(sockaddr_in)與IPV6套接字(sockaddr_in6)
ipv6_clientdata = (const struct sockaddr_in6 *)&sockStor;
ipv4_storeddata = (const struct sockaddr_in *)&(_stData[index].clientaddr);
if((ipv6_clientdata->sin6_port == ipv4_storeddata->sin_port) &&
(ipv6_clientdata->sin6_addr.in6_u.u6_addr32[3] == ipv4_storeddata->sin_addr.s_addr)
)
{
addrfound = true;
}
我想知道這種方法是否是與IPV4地址比較IPV6映射IPv4地址的妥善解決或有任何其他更好的辦法。
我承認我沒有太多的IPv6經驗,但不會例如即使它是IPv6映射的IPv4地址,recvfrom也返回源地址作爲AF_INET6? – 2012-07-30 09:11:36
對不起,我跳過/忘記提及以下功能。服務器通過兩種方式獲取客戶端地址。 1)第一次與客戶端通過UDP進行通信2)客戶端可能通過TCP將其UDP連接細節作爲XML數據發佈到服務器。在這種情況下,客戶將只提供IPV4地址。 – 2012-07-30 09:13:42
在比較最後的32位之前,還需要檢查前80位是否爲零,接下來的16位是否爲1。否則,您不知道您是否正在處理映射爲IPV6的IPV4。 – 2012-07-30 10:08:17