Die Kernfunktionen der Socket-Programmierschnittstelle - die Funktionen zum Erzeugen und Löschen von Transportendpunkten sowie zum Senden und Empfangen von TCP- oder UDP-Daten - sind von vornherein protokollunabhängig. Protokollspezifische Adressen werden als anonyme Zeiger übergeben, um neue Transportendpunkte zu erzeugen; Transportendpunkte werden danach durch einen ganzzahligen Dateideskriptor angesprochen.
Portable Programme, die sowohl in einer IPv4- als auch in einer IPv6-Umgebung lauffähig sein sollen, können durch die Verwendung der POSIX-Funktion getaddrinfo() protokollunabhängig entwickelt werden [17].
Die Funktion getaddrinfo() wird im einfachsten Fall mit einem Stationsnamen und einem Dienstnamen als Parameter aufgerufen und liefert als Ergebnis eine Liste von Strukturen des Typs addrinfo:
struct addrinfo { int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */ int ai_family; /* PF_xxx */ int ai_socktype; /* SOCK_xxx */ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ size_t ai_addrlen; /* length of ai_addr */ char *ai_canonname; /* canonical name for nodename */ struct sockaddr *ai_addr; /* binary address */ struct addrinfo *ai_next; /* next structure in linked list */ };
In dieser Struktur sind die Komponenten ai_family, ai_socktype und ai_protocol die Argumente für einen Aufruf der Funktion socket(), um einen Transportendpunkt zu erzeugen.
Weitere Funktionen, die eine protokollunanhängige Programmierung erlauben, sind folgende:
Auffällig ist, daß durch das Neudesign der Socket-Schnittstelle auch klarere Namenskonventionen eingehalten werden.
Durch die oben genannten Funktionen ist der Zeitaufwand für die Umstellung einer ''normalen'' Anwendung von IPv4 auf die gleichzeitige Verwendung von IPv4 und IPv6 sehr gering. Lediglich systemnahe Programme, die direkt mit IP-Paketen arbeiten (wie etwa ping oder traceroute), entsteht ein höherer Portierungsaufwand.
Der standardisierte Weg, um einen einfachen Klienten zu entwickeln, der gleichzeitig mit IPv4- und IPv6-Servern kommunizieren kann, stellt sich wie folgt dar 4.1 :
int fd; char *host = "server.domain"; /* Name des Servers */ char *service = "www"; /* Name des anzusprechenden Dienstes */ struct addrinfo hints, *address; hints.ai_socktype = SOCK_STREAM; /* TCP-socket */ hints.ai_flags |= AI_CANONNAME; /* kanonischen Namen verwenden */ getaddrinfo(host, service, &hints, &address); fd = socket(address->ai_family, address->ai_socktype, address->ai_protocol);
Nach der Abarbeitung dieser Programmzeilen steht mit dem Socket-Deskriptor fd ein TCP-Socket zur Verfügung, der mit den Standard-API-Funktionen wie connect(), send(), select() etc. verwendet werden kann.
In Anhang D.6.1 ist ein vollständiges Programm aufgeführt, daß einen Client für TCP oder UDP unter IPv4 oder IPv6 realisiert. In Anhang D.6.2 ist der dazugehörige Server aufgeführt.
Im September 1998 waren Standard-Programme wie finger, ftp, ping, tftp, bind, tcpdump, telnet, sendmail, apache und inn, um nur einige zu nennen, bereits auf IPv6 portiert. Dadurch steht - zumindest von Seite der Anwendungsverfügbarkeit - einer Verwendung von IPv6 im Internet nichts mehr im Wege.