Ändern der Datenstrukturen für IPv6-Winsock-Anwendungen

Wenn Sie Unterstützung für IPv6 hinzufügen, müssen Sie sicherstellen, dass Ihre Anwendung Datenstrukturen mit ordnungsgemäßer Größe definiert. Die Größe einer IPv6-Adresse ist viel größer als eine IPv4-Adresse. Strukturen, die hartcodiert sind, um die Größe einer IPv4-Adresse beim Speichern einer IP-Adresse zu verarbeiten, führen zu Problemen in Ihrer Anwendung und müssen geändert werden.

Bewährte Methode

Der beste Ansatz, um sicherzustellen, dass Ihre Strukturen ordnungsgemäß angepasst sind, besteht darin, die SOCKADDR_STORAGE-Struktur zu verwenden. Die SOCKADDR_STORAGE-Struktur berücksichtigt die IP-Adressversion nicht. Wenn die SOCKADDR_STORAGE-Struktur zum Speichern von IP-Adressen verwendet wird, können IPv4- und IPv6-Adressen mit einer Codebasis ordnungsgemäß verarbeitet werden.

Das folgende Beispiel, das aus der Datei Server.c in Anhang B stammt, identifiziert eine geeignete Verwendung der SOCKADDR_STORAGE-Struktur. Beachten Sie, dass die Struktur bei ordnungsgemäßer Verwendung wie in diesem Beispiel entweder eine IPv4- oder IPv6-Adresse ordnungsgemäß behandelt.

#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;
}

Hinweis

Die SOCKADDR_STORAGE-Struktur ist neu bei Windows XP.

 

Code, den es zu vermeiden gilt

Typischerweise verwendeten viele Anwendungen die sockaddr-Struktur, um protokollunabhängige Adressen, oder die sockaddr_in-Struktur, um IP-Adressen zu speichern. Weder die sockaddr-Struktur noch die sockaddr_in-Struktur ist groß genug, um IPv6-Adressen zu enthalten, daher sind beide nicht ausreichend, wenn Ihre Anwendung IPv6-kompatibel sein soll.

Codierungsaufgabe

So ändern Sie Ihre vorhandene Codebasis von IPv4 in IPv4- und IPv6-Interoperabilität

  1. Erwerben Sie das Hilfsprogramm Checkv4.exe. Das Hilfsprogramm ist im Microsoft Windows Software Development Kit (SDK) enthalten.
  2. Führen Sie das Hilfsprogramm Checkv4.exe gegen Ihren Code aus. Erfahren Sie mehr zur Ausführung des Hilfsprogramms Checkv4.exe für Ihre Dateien im Abschnitt Verwenden des Hilfsprogramms Checkv4.exe.
  3. Das Hilfsprogramm benachrichtigt Sie über die Verwendung von sockaddr- oder sockaddr_in-Strukturen und bietet Empfehlungen zum Austausch beider gegen die mit IPv6 kompatible Struktur SOCKADDR_STORAGE.
  4. Ersetzen Sie ggf. solche Instanzen und den zugeordneten Code, um die SOCKADDR_STORAGE-Struktur zu verwenden.

Alternativ können Sie Ihre Codebasis nach Instanzen der sockaddr- und sockaddr_in-Strukturen durchsuchen und alle diese Verwendungen (und gegebenenfalls anderen zugeordneten Code) in die SOCKADDR_STORAGE-Struktur ändern.

Hinweis

Die Strukturen addrinfo und SOCKADDR_STORAGE enthalten die Protokoll- und Adressenfamilienmitglieder (ai_family und ss_family). RFC 2553 gibt das ai_family-Mitglied von addrinfo als int an, während ss_family als short angegeben wird; daher führt eine direkte Kopie zwischen diesen Mitgliedern zu einem Compiler-Fehler.

 

IPv6-Leitfaden für Windows Sockets-Anwendungen

Dual-Stack-Sockets für IPv6-Winsock-Anwendungen

Funktionsaufrufe für IPv6-Winsock-Anwendungen

Verwendung von hartcodierten IPv4-Adressen

Probleme mit der Benutzeroberfläche für IPv6-Winsock-Anwendungen

Zugrunde liegende Protokolle für IPv6-Winsock-Anwendungen