Share via


Dual-Stack IPv6 Winsock 應用程式的通訊端

若要在 Windows XP 上使用 Service Pack 1 (SP1) 和 Windows Server 2003 支援 IPv4 和 IPv6 上的 IPv4 和 IPv6,應用程式必須建立兩個通訊端、一個通訊端與 IPv4 搭配使用,以及一個通訊端搭配 IPv6 使用。 這兩個通訊端必須由應用程式分開處理。

Windows Vista 和更新版本可讓您建立單一 IPv6 通訊端,以處理 IPv6 和 IPv4 流量。 例如,會建立 IPv6 的 TCP 接聽通訊端、進入雙重堆疊模式,並系結至埠 5001。 此雙堆疊通訊端可以接受從連線到埠 5001 的 IPv6 TCP 用戶端連線,以及從連線到埠 5001 的 IPv4 TCP 用戶端進行連線。 這項功能可大幅簡化應用程式設計,並減少在兩個不同的通訊端上張貼作業所需的資源額外負荷。

建立Dual-Stack通訊端

根據預設,在 Windows Vista 上建立的 IPv6 通訊端和更新版本只會透過 IPv6 通訊協定運作。 若要將 IPv6 通訊端設為雙堆疊通訊端,必須在通訊端系結至 IP 位址之前,使用IPV6_V6ONLY通訊端選項呼叫setockopt函式,才能將此值設定為零。 當 IPV6_V6ONLY 通訊端選項設定為零時,為 AF_INET6 位址系列建立的通訊端可用來傳送和接收 IPv6 位址或 IPv4 對應位址的封包。

具有Dual-Stack通訊端的 IP 位址

雙堆疊通訊端一律需要 IPv6 位址。 能夠與 IPv4 位址互動,需要使用 IPv4 對應 IPv6 位址格式。 任何 IPv4 位址都必須以 IPv4 對應 IPv6 位址格式來表示,這可讓 IPv6 僅應用程式與 IPv4 節點通訊。 IPv4 對應 IPv6 位址格式可讓 IPv4 節點的 IPv4 位址以 IPv6 位址表示。 IPv4 位址會編碼為 IPv6 位址的低序 32 位,而高階 96 位則保留固定前置詞 0:0:0:0:0:FFFF。 IPv4 對應 IPv6 位址格式是在 RFC 4291 中指定。 如需詳細資訊,請參閱 www.ietf.org/rfc/rfc4291.txtMstcpip.h中的IN6ADDR_SETV4MAPPED宏可用來將 IPv4 位址轉換為必要的 IPv4 對應 IPv6 位址格式。

如果基礎通訊協定實際上是 IPv4,則 IPv4 位址會對應到 IPv4 對應 IPv6 位址格式。 也就是說, SOCKADDR 結構中的數列欄位表示AF_INET6,但 IPv4 對應 IPv6 位址會編碼在 IPv6 位址結構中。 對於接聽模式中的雙堆疊通訊端,這表示任何接受的 IPv4 連線都會傳回 IPv4 對應 IPv6 位址。 如果是連線到 IPv4 目的地的雙堆疊通訊端,傳遞以連線的 SOCKADDR 結構必須是 IPv4 對應 IPv6 位址。 應用程式必須小心處理這些 IPv4 對應 IPv6 位址,並只將它們與雙堆疊通訊端搭配使用。 如果要將 IP 位址傳遞至一般 IPv4 通訊端,該位址必須是一般 IPv4 位址,而不是 IPv4 對應 IPv6 位址。

使用Dual-Stack通訊端的潛在問題

應用程式的潛在陷阱是在雙堆疊通訊端上取得 IPv4 對應的 IPv6 位址,然後嘗試在不同的僅限 IPv6 通訊端上使用傳回的 IP 位址。 例如, getocknamegetpeername 函式可以在雙堆疊通訊端上使用時傳回 IPv4 對應 IPv6 位址。 如果傳回的 IPv4 對應 IPv6 位址接著用於未設定為雙堆疊的通訊端上, (唯一 IPv6 通訊端,這是建立通訊端時的預設行為) ,則任何使用此 IPv6 僅具有 IPv4 對應 IPv6 位址的通訊端將會失敗。 IPv4 對應 IPv6 位址格式只能在雙堆疊通訊端上使用。

在雙堆疊資料包通訊端上,如果應用程式需要 LPFN_WSARECVMSG (WSARecvMsg) 函式,才能針對透過 IPv4 接收的資料包傳回 WSAMSG 結構中的封包資訊,則 IP_PKTINFO 通訊端選項必須在通訊端上設定為 true。 如果通訊端上只有 IPV6_PKTINFO 選項設定為 true,則會針對透過 IPv6 接收的資料包提供封包資訊,但可能無法針對透過 IPv4 接收的資料包提供。

如果應用程式嘗試在雙堆疊資料包通訊端上設定 IP_PKTINFO 通訊端選項,且系統上已停用 IPv4, 則 setockopt 函式將會失敗,且 WSAGetLastError 會傳回 WSAEINVAL錯誤。 setockopt函式也會傳回這個相同的錯誤,因為發生其他錯誤。 如果應用程式嘗試在雙堆疊通訊端上設定IPPROTO_IP層級通訊端選項,且 WSAEINVAL失敗,則應用程式應該判斷本機電腦上是否停用 IPv4。 其中一個可用來偵測 IPv4 是否已啟用或停用的方法,就是呼叫 通訊端 函式,並將 af 參數設定為 AF_INET,以嘗試並建立 IPv4 通訊端。 如果 通訊端 函式失敗,且 WSAGetLastError 傳回 WSAEAFNOSUPPORT的錯誤,表示 IPv4 未啟用。 在此情況下,嘗試設定IP_PKTINFO通訊端選項時,應用程式可能會忽略 setockopt 函式失敗。 否則嘗試設定IP_PKTINFO通訊端選項時發生失敗,應視為非預期的錯誤。

若是使用 WSASendMsg 函式傳送資料包,而應用程式想要指定要使用的特定本機 IP 來源位址時,要處理的雙堆疊通訊端,取決於目的地 IP 位址。 傳送至 IPv4 目的地位址或 IPv4 對應 IPv6 目的地位址時,傳入lpMsg參數所指向之 WSAMSG結構的其中一個控制項資料物件,應該包含in_pktinfo結構,其中包含要用於傳送的本機 IPv4 來源位址。 傳送至不是 IPv4 對應 IPv6 位址的 IPv6 目的地位址時,lpMsg參數所指向之 WSAMSG結構中所傳遞的其中一個控制資料物件,應該包含in6_pktinfo結構,其中包含要用於傳送的本機 IPv6 來源位址。

Windows 通訊端應用程式的 IPv6 指南

變更 IPv6 Winsock Appications 的資料結構

IPv6 Winsock 應用程式的函式呼叫

使用硬式編碼的 IPv4 位址

IPv6 Winsock 應用程式的使用者介面問題

IPv6 Winsock 應用程式的基礎通訊協定

getpeername

getsockname

in_pktinfo

in6_pktinfo

IP_PKTINFO

IPV6_PKTINFO

setsockopt

LPFN_WSARECVMSG (WSARecvMsg)

WSASendMsg