Verbindung IPv4-Clients auf IPv6-server: connection refused

Bin ich experimentiert mit IPv6-sockets, insbesondere die "dual-stack" - Funktion angeboten, die auf Windows Vista und höher, und offenbar auf Unix standardmäßig. Ich finde, dass wenn ich Binde meinen server an eine bestimmte IP-Adresse oder den Hostnamen Auflösung von meinem lokalen Rechner, ich kann nicht akzeptieren eine Verbindung von einem IPv4-client. Wenn ich binden INADDR_ANY, kann ich allerdings.

Bitte betrachten Sie den folgenden code für meinen server. Sie können sehen, dass ich von Microsoft halten Beratung mit der Erstellung eines IPv6-socket, dann die Einstellung IPV6_V6ONLY flag auf null:

addrinfo* result, *pCurrent, hints;

memset(&hints, 0, sizeof hints);    //Must do this!
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;     //We intend to use the addrinfo in a call to connect().  (I know it is ignored if we specify a server to connect to...)

int nRet = getaddrinfo("powerhouse", "82", &hints, &result);

SOCKET sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);

int no = 0;
if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&no, sizeof(no)) != 0)
    return -1;

if (bind(sock, result->ai_addr, result->ai_addrlen) ==  SOCKET_ERROR)
    return -1;

if (listen(sock, SOMAXCONN) == SOCKET_ERROR)
    return -1;

SOCKET sockClient = accept(sock, NULL, NULL);

Hier ist der code für meine Kunden. Sie können sehen, ich erstellen Sie einen IPv4-socket und versucht, eine Verbindung zu meinem server:

addrinfo* result, *pCurrent, hints;

memset(&hints, 0, sizeof hints);    //Must do this!
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;

if (getaddrinfo("powerhouse", "82", &hints, &result) != 0)
    return -1;

SOCKET sock = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
int nRet = connect(sock, result->ai_addr, result->ai_addrlen);

Das Ergebnis von meinem Aufruf verbinden ist immer 10061: Verbindung verweigert.

Wenn ich meine server-code zu binden :: (oder übergeben Sie einen NULL-host zu getaddrinfo() (das gleiche)), und mein client-code, um eine NULL-host in die getaddrinfo () - Aufruf, dann die V4-client kann die Verbindung in Ordnung.

Kann mir jemand erklären, warum bitte? Ich habe nicht irgendetwas Lesen, was müssen wir angeben, eine NULL-host (daher verwenden INADDR_ANY) wenn wir wollen, dass dual-socket-Verhalten. Dies kann nicht vorgeschrieben werden, weil das, was ich haben einen mehrfach vernetzten host und möchte ich akzeptieren IPv4 auf nur einige der verfügbaren IP-Adressen?

BEARBEITEN 15/05/2013:

Dies ist die relevante Dokumentation, die Sie bekommen hat mich verwirrt, warum mein code nicht funktioniert:

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

"Windows Vista und höher bieten die Möglichkeit, eine einzelne IPv6
Buchse, die mit IPv6 und IPv4-Verkehr. Zum Beispiel, ein TCP
socket für IPv6 erstellt, in dual-stack-Modus, und
gebunden an port 5001. Dieser dual-stack-socket akzeptiert verbindungen aus
IPv6-TCP-clients, die eine Verbindung zu port 5001 und von IPv4-TCP-clients
die Verbindung zu port 5001."

"Standardmäßig eine IPv6-socket erstellt, die auf Windows Vista und höher nur
betreibt über das IPv6-Protokoll. Um eine IPv6-socket-in
ein dual-stack-Buchse, die setsockopt-Funktion muss aufgerufen werden, mit der
IPV6_V6ONLY socket-option, um diesen Wert auf null gesetzt, bevor die Steckdose
ist gebunden an eine IP-Adresse. , Wenn die IPV6_V6ONLY socket-option gesetzt ist
zu null, wird ein socket erstellt, für die Adressfamilie AF_INET6 verwendet werden kann
zum senden und empfangen von Paketen zu und von eine IPv6-Adresse oder ein IPv4 -
zugeordnete Adresse.
(Hervorhebung von mir)"

Sie müssen eine IPv4-Endpunkt für IPv4-verbindungen, die bind ist explizit eine IPv6-Endpunkt, und nicht eine wildcard.
Ich sehe nicht, was du meinst, sorry. Können Sie das klären?
Verbindlich implementiert einen filter, um nur die Daten annehmen mit der destination address matching der gebundenen Adresse. IPv4-Pakete haben eine Ziel-IPv4-Adresse wird daher abgelehnt.
Danke, ich habe das Prinzip jetzt verinnerlicht, aber durch den Aufruf von setsockopt mit IPPROTO_IPV6 ich - laut Dokumentation - aktivieren Sie diese Buchse, um auch eingehende IPv4-verbindungen. Siehe auch den Kommentar habe ich unten geschrieben auf Sander ' s Kommentar...

InformationsquelleAutor Wad | 2013-05-10

Schreibe einen Kommentar