Fonction WSAConnectByList (winsock2.h)

La fonction WSAConnectByList établit une connexion à un des points de terminaison possibles représentés par un ensemble d’adresses de destination (noms d’hôtes et ports). Cette fonction prend toutes les adresses de destination qui lui sont passées et toutes les adresses sources de l’ordinateur local, et tente de se connecter à l’aide de toutes les combinaisons d’adresses possibles avant d’abandonner.

Cette fonction prend en charge les adresses IPv4 et IPv6.

Syntaxe

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
);

Paramètres

[in] s

Descripteur qui identifie un socket non lié et non connecté. Notez que contrairement à d’autres appels Winsock pour établir une connexion (par exemple, WSAConnect), la fonction WSAConnectByList nécessite un socket non lié.

[in] SocketAddress

Pointeur vers une structure de SOCKET_ADDRESS_LIST qui représente l’adresse de destination et les paires de ports possibles à connecter à un homologue. Il incombe à l’application de renseigner le numéro de port dans la structure de chaque SOCKET_ADDRESS dans le SOCKET_ADDRESS_LIST.

[in, out] LocalAddressLength

En entrée, un pointeur vers la taille, en octets, de la mémoire tampon LocalAddress fournie par l’appelant. Lors de la sortie, un pointeur vers la taille, en octets, du SOCKADDR pour l’adresse locale stockée dans la mémoire tampon LocalAddress remplie par le système une fois l’appel terminé.

[out] LocalAddress

Pointeur vers la structure SOCKADDR qui reçoit l’adresse locale de la connexion. La taille du paramètre correspond exactement à la taille retournée dans LocalAddressLength. Il s’agit des mêmes informations que celles qui seraient retournées par la fonction getsockname . Ce paramètre peut être NULL, auquel cas, le paramètre LocalAddressLength est ignoré.

[in, out] RemoteAddressLength

En entrée, un pointeur vers la taille, en octets, de la mémoire tampon RemoteAddress fournie par l’appelant. Lors de la sortie, un pointeur vers la taille, en octets, du SOCKADDR pour l’adresse distante stockée dans la mémoire tampon RemoteAddress remplie par le système une fois l’appel terminé.

[out] RemoteAddress

Pointeur vers la structure SOCKADDR qui reçoit l’adresse distante de la connexion. Il s’agit des mêmes informations que celles qui seraient retournées par la fonction getpeername . Ce paramètre peut être NULL, auquel cas, remoteAddressLength est ignoré.

[in] timeout

Temps, en millisecondes, d’attendre une réponse de l’application distante avant d’arrêter l’appel. Ce paramètre peut avoir la valeur NULL , auquel cas WSAConnectByList se termine une fois la connexion établie ou après qu’une connexion a été tentée et a échoué sur toutes les paires d’adresses locales-distantes possibles.

[in] Reserved

Réservé pour une implémentation future. Ce paramètre doit avoir la valeur NULL.

Valeur retournée

Si une connexion est établie, WSAConnectByList retourne TRUE et les paramètres LocalAddress et RemoteAddress sont renseignés si ces mémoires tampons ont été fournies par l’appelant.

Si l’appel échoue, FALSE est retourné. WSAGetLastError peut ensuite être appelé pour obtenir des informations d’erreur étendues.

Code de retour Description
WSAEHOSTUNREACH
L’hôte passé en tant que paramètre nodename était inaccessible.
WSAEINVAL
Un paramètre non valide a été transmis à la fonction. Le paramètre Reserved doit avoir la valeur NULL.
WSAENOBUFS
Une mémoire suffisante n’a pas pu être allouée.
WSAENOTSOCK
Un socket non valide a été passé à la fonction. Le paramètre s ne doit pas être INVALID_SOCKET ou NULL.
WSAETIMEDOUT
Aucune réponse de l’application distante n’a été reçue avant le dépassement du paramètre de délai d’attente .

Remarques

WSAConnectByList est similaire à la fonction WSAConnectByName . Au lieu de prendre un nom d’hôte et un nom de service (port), WSAConnectByList prend une liste d’adresses (adresses hôtes et ports) et se connecte à l’une des adresses. La fonction WSAConnectByList est conçue pour prendre en charge les scénarios de collaboration d’égal à égal dans lesquels une application doit se connecter à n’importe quel nœud disponible à partir d’une liste de nœuds potentiels. WSAConnectByList est compatible avec les versions IPv6 et IPv4.

L’ensemble des destinations possibles, représenté par une liste d’adresses, est fourni par l’appelant. WSAConnectByList ne se contente pas d’essayer de se connecter à l’une des nombreuses adresses de destination. Plus précisément, la fonction prend toutes les adresses distantes transmises par l’appelant, toutes les adresses locales, puis tente d’abord une connexion à l’aide de paires d’adresses ayant les plus de chances de succès. Par conséquent, WSAConnectByList garantit non seulement que la connexion sera établie si une connexion est tout à fait possible, mais réduit également le temps d’établissement de la connexion.

L’appelant peut spécifier les mémoires tampons et longueurs LocalAddress et RemoteAddress pour déterminer les adresses locales et distantes pour lesquelles la connexion a été établie avec succès.

Le paramètre de délai d’attente permet à l’appelant de limiter le temps passé par la fonction à établir une connexion. En interne, WSAConnectByList effectue plusieurs opérations (tentatives de connexion). Entre chaque opération, le paramètre de délai d’expiration est vérifié pour voir si le délai d’expiration a été dépassé et, si c’est le cas, l’appel est abandonné. Notez qu’une opération individuelle (connexion) n’est pas interrompue une fois le délai d’expiration dépassé, de sorte que l’appel WSAConnectByList peut prendre plus de temps que la valeur spécifiée dans le paramètre de délai d’expiration .

WSAConnectByList présente des limitations : il fonctionne uniquement pour les sockets orientés connexion, tels que ceux de type SOCK_STREAM. La fonction ne prend pas en charge les E/S qui se chevauchent ou ne bloquent pas le comportement. WSAConnectByList est bloqué même si le socket est en mode non bloquant. WSAConnectByList essaie de se connecter (une par une) aux différentes adresses fournies par l’appelant. Potentiellement, chacune de ces tentatives de connexion peut échouer avec un code d’erreur différent. Étant donné qu’un seul code d’erreur peut être retourné, la valeur retournée est le code d’erreur de la dernière tentative de connexion.

Pour permettre aux adresses IPv6 et IPv4 d’être transmises dans la liste d’adresses unique acceptée par la fonction, les étapes suivantes doivent être effectuées avant d’appeler la fonction :

  • La fonction setsockopt doit être appelée sur un socket créé pour la famille d’adresses AF_INET6 afin de désactiver l’option de socket IPV6_V6ONLY avant d’appeler WSAConnectByList. Pour ce faire, appelez la fonction setsockopt sur le socket avec le paramètre de niveau défini sur IPPROTO_IPV6 (consultez options de socket IPPROTO_IPV6), le paramètre optname défini sur IPV6_V6ONLY et la valeur du paramètre optvalue définie sur zéro .
  • Toutes les adresses IPv4 doivent être représentées dans le format d’adresse IPv6 mappée par IPv4, qui permet à une application IPv6 uniquement de communiquer avec un nœud IPv4. Le format d’adresse IPv6 mappé iPv4 permet de représenter l’adresse IPv4 d’un nœud IPv4 en tant qu’adresse IPv6. L’adresse IPv4 est encodée dans les 32 bits de bas ordre de l’adresse IPv6, et les 96 bits d’ordre élevé contiennent le préfixe fixe 0:0:0:0:0:0:FFFF. Le format d’adresse IPv6 mappé IPv4 est spécifié dans RFC 4291. Pour plus d’informations, consultez www.ietf.org/rfc/rfc4291.txt. La macro IN6ADDR_SETV4MAPPED dans Mstcpip.h peut être utilisée pour convertir une adresse IPv4 au format d’adresse IPv6 IPv4 requis.

Les tableaux de pointeurs transmis dans le paramètre SocketAddressList pointent vers un tableau de structures SOCKET_ADDRESS , qui sont un type de données générique. Les paramètres RemoteAddress et LocalAddress pointent également vers les structures SOCKADDR . Lorsque WSAConnectByList est appelé, il est prévu qu’un type d’adresse de socket spécifique au protocole réseau ou à la famille d’adresses utilisé soit en fait passé dans ces paramètres. Par conséquent, pour les adresses IPv4, un pointeur vers une structure sockaddr_in est converti en pointeur vers SOCKADDR lorsqu’il est passé en tant que paramètre. Pour les adresses IPv6, un pointeur vers une structure sockaddr_in6 est converti en pointeur vers SOCKADDR lorsqu’il est passé en tant que paramètre. Le paramètre SocketAddressList peut contenir des pointeurs vers un mélange d’adresses IPv4 et IPv6. Ainsi, certains SOCKET_ADDRESS pointeurs peuvent être vers sockaddr_in structures et d’autres peuvent être vers sockaddr_in6 structures. S’il est prévu que des adresses IPv6 puissent être utilisées, les paramètres RemoteAddress et LocalAddress doivent pointer vers sockaddr_in6 structures et être convertis en structures SOCKADDR . Les paramètres RemoteAddressLength et LocalAddressLength doivent représenter la longueur de ces structures plus grandes.

Lorsque la fonction WSAConnectByList retourne TRUE, le socket s est dans l’état par défaut d’un socket connecté. Le socket s n’active pas les propriétés ou options définies précédemment tant que SO_UPDATE_CONNECT_CONTEXT n’est pas défini sur le socket. Utilisez la fonction setsockopt pour définir l’option SO_UPDATE_CONNECT_CONTEXT.

Par exemple :

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

int iResult = 0;

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

Note Lors de l’émission d’un appel Winsock bloquant tel que WSAConnectByList avec le paramètre dedélai d’attente défini sur NULL, Winsock peut avoir besoin d’attendre qu’un événement réseau puisse se terminer. Winsock effectue une attente alertable dans cette situation, qui peut être interrompue par un appel de procédure asynchrone (APC) planifié sur le même thread. L’émission d’un autre appel Winsock bloquant à l’intérieur d’un APC qui a interrompu un appel Winsock bloquant en cours sur le même thread entraîne un comportement non défini et ne doit jamais être tenté par les clients Winsock.
 
Windows Phone 8 : cette fonction est prise en charge pour les applications du Store Windows Phone Windows Phone 8 et versions ultérieures.

Windows 8.1 et Windows Server 2012 R2 : cette fonction est prise en charge pour les applications du Windows Store sur Windows 8.1, Windows Server 2012 R2 et versions ultérieures.

Exemples

Établissez une connexion à l’aide de WSAConnectByList.

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

Configuration requise

   
Client minimal pris en charge Windows 8.1, Windows Vista [applications de bureau | Applications UWP]
Serveur minimal pris en charge Windows Server 2003 [applications de bureau | applications UWP]
Plateforme cible Windows
En-tête winsock2.h
Bibliothèque Ws2_32.lib
DLL Ws2_32.dll

Voir aussi

IPPROTO_IPV6 Socket Options

SOCKADDR

SOCKET_ADDRESS

SOCKET_ADDRESS_LIST

WSAConnect

WSAConnectByName

WSAGetLastError

getaddrinfo

getpeername

getsockname

setsockopt