IPv4 經營 20 餘年,位址耗盡已成定局。IPv6 擁有 128 位元龐大位址空間、內建 QoS、簡化封包頭等優勢,將逐步取代 IPv4。對網路程式開發者而言,掌握 IPv6 程式設計已成必修課。本文以實例導向方式,涵蓋 Windows 2000/XP 環境建置、API 差異對照、關鍵資料結構、完整 UDP 通訊範例。
tpipv6-001205-SP3-IE6(Microsoft IPv6 Technology Preview)setup\hotfix.exe 安裝netsh interface ipv6 install // 或命令列:ipv6 install
net start tcpip6 // 啟用
net stop tcpip6 // 停用
ipv6 adu 介面索引/位址 // 新增位址
ipv6 adu 介面索引/位址 lifetime 0 // 刪除位址(壽命設 0)
ping6 目標位址 // IPv6 ping
// IPv4
struct sockaddr_in {
u_char sin_len;
u_char sin_family; // AF_INET
u_short sin_port;
struct in_addr sin_addr; // 32-bit
char sin_zero[8];
};
struct in_addr { u_int32_t s_addr; };
// IPv6
struct sockaddr_in6 {
u_char sin6_len;
u_char sin6_family; // AF_INET6
u_int16_t sin6_port;
u_int32_t sin6_flowinfo; // 流標籤
struct in6_addr sin6_addr; // 128-bit
u_int32_t sin6_scope_id; // 範圍 ID
};
struct in6_addr { u_int8_t __u6_addr8[16]; };
| IPv4 專用 | IPv4/IPv6 通用 | 功能 |
|---|---|---|
| inet_aton() | inet_pton() | 字串 → 二進制位址 |
| inet_ntoa() | inet_ntop() | 二進制位址 → 字串 |
| gethostbyname() | getipnodebyname() / getaddrinfo() | 主機名 → 位址 |
| gethostbyaddr() | getipnodebyaddr() / getnameinfo() | 位址 → 主機名 |
新增強大函數:getaddrinfo()、getnameinfo() — 統一處理位址/名稱解析,支援 IPv4/IPv6 雙棧,建議優先使用。
socket()、bind()、send()/sendto()、recv()/recvfrom()、accept()、listen() — 參數型別改為通用結構體,邏輯不變。
recvfrom 有已知問題)#include
#include
#include "tpipv6.h" // IPv6 Tech Preview 頭檔
#pragma comment(lib, "ws2_32")
ADDRINFOW hints = {}, *res = NULL;
hints.ai_family = AF_INET6; // 指定 IPv6
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
hints.ai_flags = AI_NUMERICHOST;
int rc = getaddrinfo(targetIP, L"2000", &hints, &res);
if (rc != 0) { /* 錯誤處理 */ }
SOCKET s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
bind(s, res->ai_addr, res->ai_addrlen);
WSAAsyncSelect(s, hWnd, UM_PACKET, FD_READ); // 非同步通知
getaddrinfo(destIP, L"2000", &hints, &res);
sendto(s, msg, len, 0, res->ai_addr, res->ai_addrlen);
LRESULT OnPacket(WPARAM wParam, LPARAM lParam)
{
char buf[128];
sockaddr_in6 sa; int saLen = sizeof(sa);
int n = recv(s, buf, sizeof(buf), 0); // Win2K 用 recv 而非 recvfrom
if (n > 0) {
buf[n] = 0;
// 處理接收資料...
}
return 0;
}
sockaddr_storage(足夠容納 IPv4/IPv6)AF_INET,改用 ai_family 動態判斷IPv6 程式設計核心在於位址結構體與名稱解析函數的遷移。掌握 sockaddr_in6、getaddrinfo()、inet_ntop()/pton() 等關鍵 API,配合雙棧相容設計,即可平滑過渡。本文提供的完整 UDP 範例可作為 IPv6 網路應用開發的起點。