共用方式為


變更 IPv6 Winsock Appications 的資料結構

新增 IPv6 的支援時,您必須確定應用程式定義了適當大小的資料結構。 IPv6 位址的大小遠大於 IPv4 位址。 在儲存 IP 位址時,硬式編碼來處理 IPv4 位址大小的結構會導致應用程式中發生問題,而且必須加以修改。

最佳做法

確保結構大小正確的最佳方法是使用 SOCKADDR_STORAGE 結構。 SOCKADDR_STORAGE結構與 IP 位址版本無關。 當 SOCKADDR_STORAGE 結構用來儲存 IP 位址時,可以使用一個程式碼基底正確處理 IPv4 和 IPv6 位址。

下列範例是從附錄 B 中找到的 Server.c 檔案擷取的摘錄,可識別適當地使用 SOCKADDR_STORAGE 結構。 請注意,當此範例正確使用 結構時,會正常處理 IPv4 或 IPv6 位址。

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>

#pragma comment(lib, "Ws2_32.lib")

#define BUFFER_SIZE 512
#define DEFAULT_PORT "27015"

int main(int argc, char **argv)
{
    char Buffer[BUFFER_SIZE] = {0};
    char *Hostname;
    int Family = AF_UNSPEC;
    int SocketType = SOCK_STREAM;
    char *Port = DEFAULT_PORT;
    char *Address = NULL;
    int i = 0;
    DWORD dwRetval = 0;
    int iResult = 0;
    int FromLen = 0;
    int AmountRead = 0;

    SOCKADDR_STORAGE From;

    WSADATA wsaData;

    ADDRINFO *AddrInfo = NULL;
    ADDRINFO *AI = NULL;

    // Parse arguments
    if (argc >= 1) {
        Hostname = argv[1];
    }    

   // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed: %d\n", iResult);
        return 1;
    }

    From.ss_family = (ADDRESS_FAMILY) Family;
    
    //...
        
        return 0;
}

注意

Windows XP 的 SOCKADDR_STORAGE 結構是新的。

 

要避免的程式碼

一般而言,許多應用程式都使用 sockaddr 結構來儲存通訊協定無關的位址,或 IP 位址 的sockaddr_in 結構。 sockaddr 結構或 sockaddr_in 結構都不足以保存 IPv6 位址,因此如果應用程式與 IPv6 相容,這兩者都不足。

編碼工作

將現有的程式碼基底從 IPv4 修改為 IPv4 和 IPv6 互通性

  1. 取得Checkv4.exe公用程式。 公用程式隨附于 Microsoft Windows 軟體發展工具組 (SDK) ,可透過您的 MSDN 訂用帳戶或從網頁下載。
  2. 針對您的程式碼執行Checkv4.exe公用程式。 瞭解如何 在使用 Checkv4.exe 公用程式一節中針對檔案執行Checkv4.exe公用程式。
  3. 公用程式會警示您使用 sockaddrsockaddr_in 結構,並提供如何以 IPv6 相容結構取代 SOCKADDR_STORAGE的建議。
  4. 視需要取代任何這類實例和相關聯的程式碼,以使用 SOCKADDR_STORAGE 結構。

或者,您可以搜尋程式碼基底中的 sockaddr 和 sockaddr_in 結構實例,並) 視情況將這類使用 ( 和其他相關聯的程式碼變更為 SOCKADDR_STORAGE 結構。

注意

addrinfoSOCKADDR_STORAGE結構分別包含通訊協定和位址系列成員 (ai_familyss_family) 。 RFC 2553 會將addrinfo的ai_family成員指定為 int,而ss_family指定為簡短;因此,這些成員之間的直接複製會導致編譯器錯誤。

 

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

IPv6 Winsock 應用程式的雙堆疊通訊端

IPv6 Winsock 應用程式的函式呼叫

使用硬式編碼的 IPv4 位址

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

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