WSAConnectByList-Funktion (winsock2.h)

Die WSAConnectByList-Funktion stellt eine Verbindung mit einem aus einer Sammlung möglicher Endpunkte her, die durch eine Reihe von Zieladressen (Hostnamen und Ports) dargestellt werden. Diese Funktion akzeptiert alle an sie übergebenen Zieladressen und alle Quelladressen des lokalen Computers und versucht, eine Verbindung mit allen möglichen Adresskombinationen herzustellen, bevor sie aufgibt.

Diese Funktion unterstützt sowohl IPv4- als auch IPv6-Adressen.

Syntax

BOOL WSAConnectByList(
  [in]      SOCKET               s,
  [in]      PSOCKET_ADDRESS_LIST SocketAddress,
  [in, out] LPDWORD              LocalAddressLength,
  [out]     LPSOCKADDR           LocalAddress,
  [in, out] LPDWORD              RemoteAddressLength,
  [out]     LPSOCKADDR           RemoteAddress,
  [in]      const timeval        *timeout,
  [in]      LPWSAOVERLAPPED      Reserved
);

Parameter

[in] s

Ein Deskriptor, der einen nicht gebundenen und nicht verbundenen Socket identifiziert. Beachten Sie, dass die WSAConnectByList-Funktion im Gegensatz zu anderen Winsock-Aufrufen zum Herstellen einer Verbindung (z. B. WSAConnectConnect) einen ungebundenen Socket erfordert.

[in] SocketAddress

Ein Zeiger auf eine SOCKET_ADDRESS_LIST-Struktur , die die möglichen Zieladressen- und Portpaare zum Herstellen einer Verbindung mit einem Peer darstellt. Es liegt in der Verantwortung der Anwendung, die Portnummer in der SOCKET_ADDRESS-Struktur im SOCKET_ADDRESS_LIST auszufüllen.

[in, out] LocalAddressLength

Bei der Eingabe ein Zeiger auf die Größe des vom Aufrufer bereitgestellten LocalAddress-Puffers in Bytes. Bei der Ausgabe ein Zeiger auf die Größe des SOCKADDR für die lokale Adresse, die im LocalAddress-Puffer gespeichert ist, der nach erfolgreichem Abschluss des Aufrufs vom System ausgefüllt wird.

[out] LocalAddress

Ein Zeiger auf die SOCKADDR-Struktur , die die lokale Adresse der Verbindung empfängt. Die Größe des Parameters entspricht genau der Größe, die in LocalAddressLength zurückgegeben wird. Dies sind die gleichen Informationen, die von der getockname-Funktion zurückgegeben würden. Dieser Parameter kann NULL sein. In diesem Fall wird der Parameter LocalAddressLength ignoriert.

[in, out] RemoteAddressLength

Bei der Eingabe ein Zeiger auf die Größe des vom Aufrufer bereitgestellten RemoteAddress-Puffers in Bytes. Bei der Ausgabe wird ein Zeiger auf die Größe des SOCKADDR für die im RemoteAddress-Puffer gespeicherte Remoteadresse in Bytes angezeigt, die nach erfolgreichem Abschluss des Aufrufs vom System ausgefüllt wird.

[out] RemoteAddress

Ein Zeiger auf die SOCKADDR-Struktur , die die Remoteadresse der Verbindung empfängt. Dies sind die gleichen Informationen, die von der getpeername-Funktion zurückgegeben würden. Dieser Parameter kann NULL sein. In diesem Fall wird remoteAddressLength ignoriert.

[in] timeout

Die Zeit in Millisekunden, um auf eine Antwort von der Remoteanwendung zu warten, bevor der Aufruf abgebrochen wird. Dieser Parameter kann NULL sein. In diesem Fall wird WSAConnectByList abgeschlossen, nachdem entweder die Verbindung erfolgreich hergestellt wurde oder nachdem eine Verbindung versucht wurde und bei allen möglichen Lokalen/Remoteadressenpaaren ein Fehler aufgetreten ist.

[in] Reserved

Reserviert für die zukünftige Implementierung. Dieser Parameter muss auf NULL festgelegt werden.

Rückgabewert

Wenn eine Verbindung hergestellt wird, gibt WSAConnectByListTRUE zurück, und die Parameter LocalAddress und RemoteAddress werden ausgefüllt, wenn diese Puffer vom Aufrufer bereitgestellt wurden.

Wenn der Aufruf fehlschlägt, wird FALSE zurückgegeben. WSAGetLastError kann dann aufgerufen werden, um erweiterte Fehlerinformationen zu erhalten.

Rückgabecode Beschreibung
WSAEHOSTUNREACH
Der host, der als nodename-Parameter übergeben wurde, war nicht erreichbar.
WSAEINVAL
Es wurde ein ungültiger Parameter an die Funktion übergeben. Der Reserved-Parameter muss NULL sein.
WSAENOBUFS
Es konnte kein ausreichender Arbeitsspeicher zugewiesen werden.
WSAENOTSOCK
Ein ungültiger Socket wurde an die Funktion übergeben. Der s-Parameter darf nicht INVALID_SOCKET oder NULL sein.
WSAETIMEDOUT
Eine Antwort der Remoteanwendung wurde nicht empfangen, bevor der Timeoutparameter überschritten wurde.

Hinweise

WSAConnectByList ähnelt der WSAConnectByName-Funktion . Anstatt einen einzelnen Hostnamen und Dienstnamen (Port) zu verwenden, akzeptiert WSAConnectByList eine Liste von Adressen (Hostadressen und Ports) und stellt eine Verbindung mit einer der Adressen her. Die WSAConnectByList-Funktion wurde entwickelt, um Peer-to-Peer-Zusammenarbeitsszenarien zu unterstützen, in denen eine Anwendung eine Verbindung mit einem beliebigen verfügbaren Knoten aus einer Liste potenzieller Knoten herstellen muss. WSAConnectByList ist mit IPv6- und IPv4-Versionen kompatibel.

Der Durch eine Liste von Adressen dargestellte Satz möglicher Ziele wird vom Aufrufer bereitgestellt. WSAConnectByList bietet mehr als nur den Versuch, eine Verbindung mit einer von möglicherweise vielen Zieladressen herzustellen. Insbesondere akzeptiert die Funktion alle vom Aufrufer übergebenen Remoteadressen, alle lokalen Adressen, und versucht dann zunächst eine Verbindung mithilfe von Adresspaaren mit der höchsten Erfolgswahrscheinlichkeit. Daher stellt WSAConnectByList nicht nur sicher, dass die Verbindung hergestellt wird, wenn eine Verbindung möglich ist, sondern minimiert auch die Zeit zum Herstellen der Verbindung.

Der Aufrufer kann die Puffer und Längen von LocalAddress und RemoteAddress angeben, um die lokalen und Remoteadressen zu bestimmen, für die die Verbindung erfolgreich hergestellt wurde.

Der Timeoutparameter ermöglicht es dem Aufrufer, die Zeit zu begrenzen, die die Funktion beim Herstellen einer Verbindung aufwendet. Intern führt WSAConnectByList mehrere Vorgänge (Verbindungsversuche) aus. Zwischen jedem Vorgang wird der Timeoutparameter überprüft, um festzustellen, ob das Timeout überschritten wurde, und wenn ja, wird der Aufruf abgebrochen. Beachten Sie, dass ein einzelner Vorgang (Connect) nicht unterbrochen wird, sobald das Timeout überschritten wird, sodass das Timeout für den WSAConnectByList-Aufruf länger dauern kann als der im Timeoutparameter angegebene Wert.

WSAConnectByList hat Einschränkungen: Es funktioniert nur für verbindungsorientierte Sockets, z. B. solche vom Typ SOCK_STREAM. Die Funktion unterstützt kein überlappende E/A- oder nicht blockierende Verhalten. WSAConnectByList blockiert auch dann, wenn sich der Socket im nicht blockierenden Modus befindet. WSAConnectByList versucht, eine Verbindung (einzeln) mit den verschiedenen Vom Aufrufer bereitgestellten Adressen herzustellen. Möglicherweise schlägt jeder dieser Verbindungsversuche mit einem anderen Fehlercode fehl. Da nur ein einzelner Fehlercode zurückgegeben werden kann, ist der zurückgegebene Wert der Fehlercode aus dem letzten Verbindungsversuch.

Damit sowohl IPv6- als auch IPv4-Adressen in der von der Funktion akzeptierten einzelnen Adressliste übergeben werden können, müssen vor dem Aufrufen der Funktion die folgenden Schritte ausgeführt werden:

  • Die setockopt-Funktion muss für einen Socket aufgerufen werden, der für die AF_INET6 Adressfamilie erstellt wurde, um die Socketoption IPV6_V6ONLY vor dem Aufrufen von WSAConnectByList zu deaktivieren. Dies wird durch Aufrufen der setockopt-Funktion für den Socket mit dem level-Parameter auf IPPROTO_IPV6 (siehe IPPROTO_IPV6 Socketoptionen), dem auf IPV6_V6ONLY festgelegten optname-Parameter und dem wert des optvalue-Parameters auf Null erreicht.
  • Alle IPv4-Adressen müssen im IPv4-zugeordneten IPv6-Adressformat dargestellt werden, sodass eine reine IPv6-Anwendung mit einem IPv4-Knoten kommunizieren kann. Das IPv4-zugeordnete IPv6-Adressformat ermöglicht die Darstellung der IPv4-Adresse eines IPv4-Knotens als IPv6-Adresse. Die IPv4-Adresse wird in die niedrigen 32 Bits der IPv6-Adresse codiert, und die 96-Bits mit hoher Reihenfolge enthalten das feste Präfix 0:0:0:0:0:FFFF. Das IPv4-zugeordnete IPv6-Adressformat wird in RFC 4291 angegeben. Weitere Informationen finden Sie unter www.ietf.org/rfc/rfc4291.txt. Das IN6ADDR_SETV4MAPPED Makro in Mstcpip.h kann verwendet werden, um eine IPv4-Adresse in das erforderliche IPv4-zugeordnete IPv6-Adressformat zu konvertieren.

Die Arrays von Zeigern, die im SocketAddressList-Parameter übergeben werden, verweisen auf ein Array von SOCKET_ADDRESS Strukturen, bei denen es sich um einen generischen Datentyp handelt. Die Parameter RemoteAddress und LocalAddress verweisen ebenfalls auf SOCKADDR-Strukturen . Wenn WSAConnectByList aufgerufen wird, wird erwartet, dass ein Socketadresstyp, der für das verwendete Netzwerkprotokoll oder die verwendete Adressfamilie spezifisch ist, tatsächlich in diesen Parametern übergeben wird. Bei IPv4-Adressen wird also ein Zeiger auf eine sockaddr_in-Struktur in einen Zeiger auf SOCKADDR umgewandelt, wenn er als Parameter übergeben wird. Bei IPv6-Adressen wird ein Zeiger auf eine sockaddr_in6-Struktur in einen Zeiger auf SOCKADDR umgewandelt, wenn er als Parameter übergeben wird. Der SocketAddressList-Parameter kann Zeiger auf eine Mischung aus IPv4- und IPv6-Adressen enthalten. Daher können einige SOCKET_ADDRESS Zeiger auf sockaddr_in Strukturen und andere in der sockaddr_in6 von Strukturen sein. Wenn erwartet wird, dass IPv6-Adressen verwendet werden können, sollten die Parameter RemoteAddress und LocalAddress auf sockaddr_in6 Strukturen verweisen und in SOCKADDR-Strukturen umgewandelt werden. Die Parameter RemoteAddressLength und LocalAddressLength müssen die Länge dieser größeren Strukturen darstellen.

Wenn die WSAConnectByList-FunktionTRUE zurückgibt, befindet sich der Socket s im Standardzustand eines verbundenen Sockets. Die Sockets aktivieren zuvor festgelegte Eigenschaften oder Optionen erst, wenn SO_UPDATE_CONNECT_CONTEXT für den Socket festgelegt wurde. Verwenden Sie die setockopt-Funktion , um die Option SO_UPDATE_CONNECT_CONTEXT festzulegen.

Beispiel:

//Need to #include <mswsock.h> for SO_UPDATE_CONNECT_CONTEXT

int iResult = 0;

iResult = setsockopt( s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0 );

Hinweis Beim Ausgeben eines blockierenden Winsock-Aufrufs wie WSAConnectByList mit dem timeout-Parameter , der auf NULL festgelegt ist, muss Winsock möglicherweise auf ein Netzwerkereignis warten, bevor der Aufruf abgeschlossen werden kann. Winsock führt in dieser Situation eine warnbare Wartezeit aus, die durch einen asynchronen Prozeduraufruf (APC) unterbrochen werden kann, der für denselben Thread geplant ist. Das Ausstellen eines weiteren blockierenden Winsock-Aufrufs innerhalb eines APC, der einen fortlaufend blockierenden Winsock-Aufruf im selben Thread unterbrochen hat, führt zu undefiniertem Verhalten und darf niemals von Winsock-Clients versucht werden.
 
Windows Phone 8: Diese Funktion wird für Windows Phone Store-Apps ab Windows Phone 8 unterstützt.

Windows 8.1 und Windows Server 2012 R2: Diese Funktion wird für Windows Store-Apps unter Windows 8.1, Windows Server 2012 R2 und höher unterstützt.

Beispiele

Stellen Sie mithilfe von WSAConnectByList eine Verbindung her.

#ifndef UNICODE
#define UNICODE
#endif

#define WIN32_LEAN_AND_MEAN

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

// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")


SOCKET
OpenAndConnect(SOCKET_ADDRESS_LIST *AddressList) 
{
    SOCKET ConnSocket = INVALID_SOCKET;

    int ipv6only = 0;
    int iResult;
    BOOL bSuccess;

    SOCKADDR_STORAGE LocalAddr = {0};
    SOCKADDR_STORAGE RemoteAddr = {0};

    DWORD dwLocalAddr = sizeof(LocalAddr);
    DWORD dwRemoteAddr = sizeof(RemoteAddr);

    ConnSocket = socket(AF_INET6, SOCK_STREAM, 0);
    if (ConnSocket == INVALID_SOCKET){
        return INVALID_SOCKET;
    }

    iResult = setsockopt(ConnSocket, IPPROTO_IPV6,
        IPV6_V6ONLY, (char*)&ipv6only, sizeof(ipv6only) );
    if (iResult == SOCKET_ERROR){
        closesocket(ConnSocket);
        return INVALID_SOCKET;       
    }

    // AddressList may contain IPv6 and/or IPv4Mapped addresses
    bSuccess = WSAConnectByList(ConnSocket,
            AddressList,
            &dwLocalAddr,
            (SOCKADDR*)&LocalAddr,
            &dwRemoteAddr,
            (SOCKADDR*)&RemoteAddr,
            NULL,
            NULL);
    if (bSuccess){
        return ConnSocket;
    } else {
        return INVALID_SOCKET;
    }
}

Anforderungen

   
Unterstützte Mindestversion (Client) Windows 8.1, Windows Vista [Desktop-Apps | UWP-Apps]
Unterstützte Mindestversion (Server) Windows Server 2003 [Desktop-Apps | UWP-Apps]
Zielplattform Windows
Kopfzeile winsock2.h
Bibliothek Ws2_32.lib
DLL Ws2_32.dll

Weitere Informationen

IPPROTO_IPV6 Socketoptionen

SOCKADDR

SOCKET_ADDRESS

SOCKET_ADDRESS_LIST

WSAConnect

WSAConnectByName

WSAGetLastError

getaddrinfo

getpeername

getsockname

setsockopt