getaddrinfo und getnameinfo sind Ihre Freunde .. So weit wie möglich schlage ich vor, dass sie Ihre besten Freunde in Ihrer Suche nach IPv4 und IPv6-Unterstützung in einer bestehenden Anwendung sind.
Wenn Sie direkt IPv6-Unterstützung hinzufügen, wird das System bis zu dem Punkt abstrahiert, an dem ein unbekanntes zukünftiges IP-Protokoll ohne Code-Änderung ausgeführt werden kann.
Normalerweise, wenn Sie eine Verbindung eine Sockelstruktur ausfüllen würde, Port, Adressfamilie, IP-Adresse, Adresse/ports Umwandlung Byte-Reihenfolge zu vernetzen, usw.
Mit getaddrinfo
Sie eine IP-Adresse oder den Hostnamen und Port senden oder Port-Name, und es gibt eine verkettete Liste mit den Strukturen und alles bereit, direkt in socket()
und connect()
übergeben werden.
getaddrinfo
ist entscheidend für die mit beiden IP-Protokollen arbeiten, wie es weiß, ob der Host IPv6 oder IPv4-Konnektivität hat und es weiß, ob der Peer als auch tut, indem DNS AAAA
vs A
Aufzeichnungen suchen und dynamisch herausfindet, welches Protokoll (e) sind verfügbar, um die spezifische Verbindungsanforderung zu bedienen.
Ich rate dringend davon ab, inet_pton()
, inet_addr()
oder ähnliche Geräte zu verwenden, die IP-spezifisch sind. Auf der Windows-Plattform inet_pton()
ist nicht kompatibel mit früheren Versionen von MS Windows (XP, 2003 ua), es sei denn, Sie rollen Ihre eigenen. Beraten auch gegen separate Versionen für IPv4 und IPv6 ... Dies ist als technische Lösung nicht praktikabel, weil in naher Zukunft beide Protokolle gleichzeitig verwendet werden müssen und die Leute möglicherweise nicht im Voraus wissen, was zu verwenden ist. Die Socket-Schnittstellen sind abstrakt und es ist leicht, Dual-Stack- oder IPv6-Unterstützung zu erkennen, indem Sie versuchen, einen IPv6-Socket zu erstellen oder die IPv6-Dualstack-Socket-Option für Listener festzulegen. Es gibt keinen Grund, warum die resultierende Anwendung nicht auf einem System ausgeführt wird, das IPv6 nicht unterstützt oder kennt.
Für ausgehende Verbindungen verwenden Sie PF_UNSPEC
in getaddrinfo
, so dass die Adresse Familie für Sie ausgehende Verbindungen ausgewählt wird. Dies ist IMHO besser als der Dual-Stack-Ansatz, da es Plattformen ermöglicht, die Dual-Stack nicht unterstützen.
Bei eingehenden Verbindungen können Sie IPv4/IPv6-Sockets entweder separat binden, wenn dies aufgrund des Designs sinnvoll ist, oder Dualstack verwenden, wenn Sie keine separaten Listener verwenden können. Bei Verwendung von Dualstack gibt getnameinfo
eine IPv6-Adresse für IPv4-Adressen zurück, die IMHO ziemlich nutzlos ist. Ein kleines Dienstprogramm kann die Zeichenfolge in eine normale IPv4-Adresse konvertieren.
Aus meiner Erfahrung, wenn Sie richtig gemacht haben Sie Abhängigkeiten von bestimmten IP-Versionen entfernt und endete mit weniger Socket-Management-Code als Sie gestartet.
Es ist auch erwähnenswert, dass alle diese Anrufe in der Regel zwischen Windows, Mac OS X und Linux mit nur geringen Unterschieden hier und da portierbar sind. –