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 |
---|---|
|
L’hôte passé en tant que paramètre nodename était inaccessible. |
|
Un paramètre non valide a été transmis à la fonction. Le paramètre Reserved doit avoir la valeur NULL. |
|
Une mémoire suffisante n’a pas pu être allouée. |
|
Un socket non valide a été passé à la fonction. Le paramètre s ne doit pas être INVALID_SOCKET ou NULL. |
|
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 );
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 |