LPFN_CONNECTEX fonction de rappel (mswsock.h)
La fonction ConnectEx établit une connexion à un socket spécifié et envoie éventuellement des données une fois la connexion établie. La fonction ConnectEx est uniquement prise en charge sur les sockets orientés connexion.
Syntaxe
LPFN_CONNECTEX LpfnConnectex;
BOOL LpfnConnectex(
[in] SOCKET s,
[in] const sockaddr *name,
[in] int namelen,
[in, optional] PVOID lpSendBuffer,
[in] DWORD dwSendDataLength,
[out] LPDWORD lpdwBytesSent,
[in] LPOVERLAPPED lpOverlapped
)
{...}
Paramètres
[in] s
Descripteur qui identifie un socket non connecté, précédemment lié. Pour plus d'informations, consultez la section Notes.
[in] name
Pointeur vers
structure sockaddr qui spécifie l’adresse à laquelle se connecter. Pour IPv4, le sockaddr contient AF_INET pour la famille d’adresses, l’adresse IPv4 de destination et le port de destination. Pour IPv6, la structure sockaddr contient AF_INET6 pour la famille d’adresses, l’adresse IPv6 de destination, le port de destination et peut contenir des informations supplémentaires sur le flux IPv6 et l’id d’étendue.
[in] namelen
Longueur, en octets, de la structure sockaddr pointée vers le paramètre name .
[in, optional] lpSendBuffer
Pointeur vers la mémoire tampon à transférer après l’établissement d’une connexion. Ce paramètre est facultatif. Si l’option TCP_FASTOPEN est activée sur s avant l’appel de ConnectEx , certaines de ces données peuvent être envoyées lors de l’établissement de la connexion.
[in] dwSendDataLength
Longueur, en octets, des données pointées par le paramètre lpSendBuffer . Ce paramètre est ignoré lorsque le paramètre lpSendBuffer a la valeur NULL.
[out] lpdwBytesSent
En cas de retour réussi, ce paramètre pointe vers une valeur DWORD qui indique le nombre d’octets qui ont été envoyés après l’établissement de la connexion. Les octets envoyés proviennent de la mémoire tampon vers laquelle pointe le paramètre lpSendBuffer . Ce paramètre est ignoré lorsque le paramètre lpSendBuffer a la valeur NULL.
[in] lpOverlapped
Structure CHEVAUCHEMENT UTILISÉE pour traiter la demande. Le paramètre lpOverlapped doit être spécifié et ne peut pas être NULL.
Valeur retournée
En cas de réussite, la fonction ConnectEx retourne TRUE. En cas d’échec, la fonction retourne FALSE. Utilisez la fonction WSAGetLastError pour obtenir des informations d’erreur étendues. Si un appel à la fonction WSAGetLastError retourne ERROR_IO_PENDING, l’opération a été lancée avec succès et est en cours. Dans de telles circonstances, l’appel peut toujours échouer lorsque l’opération qui se chevauche se termine.
Si le code d’erreur retourné est WSAECONNREFUSED, WSAENETUNREACH ou WSAETIMEDOUT, l’application peut appeler ConnectEx, WSAConnect ou se reconnecter sur le même socket.
Code d'erreur | Description |
---|---|
Un appel de fonction WSAStartup réussi doit se produire avant d’utiliser ConnectEx. | |
Le sous-système réseau a échoué. | |
L’adresse locale du socket est déjà utilisée et le socket n’a pas été marqué pour permettre la réutilisation de l’adresse avec SO_REUSEADDR. Cette erreur se produit généralement pendant une opération de liaison , mais l’erreur peut être retardée jusqu’à un appel de fonction ConnectEx , si la fonction de liaison a été appelée avec une adresse générique (INADDR_ANY ou in6addr_any) spécifiée pour l’adresse IP locale. Une adresse IP spécifique doit être implicitement liée par la fonction ConnectEx . | |
Un appel de fonction connect, WSAConnect ou ConnectEx sans blocage est en cours sur le socket spécifié. | |
L’adresse distante n’est pas une adresse valide, telle que ADDR_ANY (la fonction ConnectEx n’est prise en charge que pour les sockets orientés connexion). | |
Impossible d'utiliser les adresses figurant dans la famille spécifiée avec ce socket. | |
La tentative de connexion a été rejetée. | |
Le paramètre name, lpSendBuffer ou lpOverlapped n’est pas une partie valide de l’espace d’adressage utilisateur, ou namelen est trop petit. | |
Le paramètre s est un socket indépendant ou d’écoute. | |
Le socket est déjà connecté. | |
Le réseau ne peut pas être atteint à partir de cet hôte en ce moment. | |
Une opération de socket a été tentée sur un hôte impossible à atteindre. | |
Aucun espace de mémoire tampon n’est disponible ; le socket ne peut pas être connecté. | |
Le descripteur n’est pas un socket. | |
La tentative de connexion a expiré sans établir de connexion. |
Remarques
La fonction ConnectEx combine plusieurs fonctions de socket en une seule transition API/noyau. Les opérations suivantes sont effectuées lorsqu’un appel à la fonction ConnectEx se termine correctement :
- Une nouvelle connexion est établie.
- Un bloc de données facultatif est envoyé après l’établissement de la connexion.
Pour les applications ciblées sur Windows Vista et versions ultérieures, envisagez d’utiliser la fonction WSAConnectByList ou WSAConnectByName , ce qui simplifie considérablement la conception des applications clientes.
La fonction ConnectEx ne peut être utilisée qu’avec des sockets orientés connexion. Le socket passé dans le paramètre s doit être créé avec un type de socket SOCK_STREAM, SOCK_RDM ou SOCK_SEQPACKET.
Le paramètre lpSendBuffer pointe vers une mémoire tampon de données à envoyer une fois la connexion établie. Le paramètre dwSendDataLength spécifie la longueur en octets de ces données à envoyer. Une application peut demander à envoyer une mémoire tampon volumineuse de données à l’aide de ConnectEx de la même façon que les fonctions d’envoi et WSASend peuvent être utilisées. Toutefois, il est fortement déconseillé aux développeurs d’envoyer une mémoire tampon énorme en un seul appel à l’aide de ConnectEx, car cette opération utilise une grande quantité de ressources de mémoire système jusqu’à ce que la mémoire tampon entière ait été envoyée.
Si la fonction ConnectEx réussit, une connexion a été établie et toutes les données pointées par le paramètre lpSendBuffer ont été envoyées à l’adresse spécifiée dans la structure sockaddr pointée vers le paramètre name .
La fonction ConnectEx utilise des E/S qui se chevauchent. Par conséquent, la fonction ConnectEx permet à une application de traiter un grand nombre de clients avec relativement peu de threads. En revanche, la fonction WSAConnect , qui n’utilise pas d’E/S superposées, nécessite généralement un thread distinct pour traiter chaque demande de connexion lors de la réception de demandes simultanées.
Les sockets orientés connexion ne parviennent souvent pas à terminer immédiatement leur connexion. Par conséquent, l’opération est lancée et la fonction retourne immédiatement avec l’erreur ERROR_IO_PENDING ou WSA_IO_PENDING. Lorsque l’opération de connexion se termine et que la réussite ou l’échec est atteint, status est signalé à l’aide du mécanisme de notification d’achèvement indiqué dans lpOverlapped. Comme pour tous les appels de fonction qui se chevauchent, vous pouvez utiliser des événements ou des ports d’achèvement comme mécanisme de notification d’achèvement. Le paramètre lpNumberOfBytesTransferred de la fonction GetQueuedCompletionStatus , GetOverlappedResult ou WSAGetOverlappedResult indique le nombre d’octets envoyés dans la requête.
Une fois la fonction ConnectEx terminée, les handles de socket peuvent être passés uniquement aux fonctions suivantes :
Si la fonction TransmitFile est appelée sur un socket précédemment connecté avec des indicateurs TF_DISCONNECT et TF_REUSE_SOCKET, le socket spécifié est retourné à un état dans lequel il n’est pas connecté, mais toujours lié. Dans ce cas, le handle du socket peut être passé à la fonction ConnectEx dans son paramètre s , mais le socket ne peut pas être réutilisé dans un appel de fonction AcceptEx . De même, le socket accepté réutilisé à l’aide de la fonction TransmitFile ne peut pas être utilisé dans un appel à ConnectEx. Notez que dans le cas d’un socket réutilisé, ConnectEx est soumis au comportement du transport sous-jacent. Par exemple, un socket TCP peut être soumis à l’état TIME_WAIT TCP, ce qui entraîne le retard de l’appel ConnectEx .
Lorsque la fonction ConnectEx 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 );
La fonction getsockopt peut être utilisée avec l’option de socket SO_CONNECT_TIME pour case activée si une connexion a été établie pendant que ConnectEx est en cours. Si une connexion a été établie, la valeur retournée dans le paramètre optval passé à la fonction getsockopt est le nombre de secondes pendant lesquelles le socket a été connecté. Si le socket n’est pas connecté, le paramètre optval retourné contient 0xFFFFFFFF. La vérification d’une connexion de cette manière est nécessaire pour déterminer si les connexions ont été établies pendant un certain temps sans envoyer de données ; dans ce cas, il est recommandé d’arrêter ces connexions.
Par exemple :
//Need to #include <mswsock.h> for SO_CONNECT_TIME
int seconds;
int bytes = sizeof(seconds);
int iResult = 0;
iResult = getsockopt( s, SOL_SOCKET, SO_CONNECT_TIME,
(char *)&seconds, (PINT)&bytes );
if ( iResult != NO_ERROR ) {
printf( "getsockopt(SO_CONNECT_TIME) failed with error: %u\n",
WSAGetLastError() );
}
else {
if (seconds == 0xFFFFFFFF)
printf("Connection not established yet\n");
else
printf("Connection has been established %ld seconds\n",
seconds);
}
Si le paramètre address de la structure sockaddr pointée vers le paramètre name est tous les zéros, ConnectEx renvoie l’erreur WSAEADDRNOTAVAIL. Toute tentative de reconnexion d’une connexion active échoue avec le code d’erreur WSAEISCONN.
Lorsqu’un socket connecté est fermé pour une raison quelconque, il est recommandé d’ignorer le socket et de créer un nouveau socket. Le raisonnement est qu’il est plus sûr de supposer que lorsque les choses vont mal sur un socket connecté pour une raison quelconque, l’application doit ignorer le socket et créer à nouveau le socket nécessaire afin de revenir à un point stable.
Si la fonction DisconnectEx est appelée avec l’indicateur TF_REUSE_SOCKET , le socket spécifié est retourné à un état dans lequel il n’est pas connecté, mais toujours lié. Dans ce cas, le handle du socket peut être passé à la fonction ConnectEx dans son paramètre s .
L’intervalle de temps qui doit s’écouler avant que TCP puisse libérer une connexion fermée et réutiliser ses ressources est appelé état TIME_WAIT ou état 2MSL. Pendant ce temps, la connexion peut être rouverte à beaucoup moins de frais pour le client et le serveur que l’établissement d’une nouvelle connexion.
Le comportement TIME_WAIT est spécifié dans RFC 793, ce qui nécessite que TCP conserve une connexion fermée pendant un intervalle au moins égal à deux fois la durée de vie maximale du segment (MSL) du réseau. Lorsqu’une connexion est libérée, sa paire de sockets et les ressources internes utilisées pour le socket peuvent être utilisées pour prendre en charge une autre connexion.
Windows TCP rétablit un état TIME_WAIT après la fermeture d’une connexion. Dans l’état TIME_WAIT, une paire de sockets ne peut pas être réutilisée. La période TIME_WAIT est configurable en modifiant le paramètre de Registre DWORD suivant qui représente la période TIME_WAIT en secondes.
HKEY_LOCAL_MACHINE\Système\Currentcontrolset\Services\TCPIP\Paramètres\TcpTimedWaitDelay
Par défaut, le MSL est défini sur 120 secondes. Le paramètre de Registre TcpTimedWaitDelay est défini par défaut sur une valeur de 240 secondes, ce qui représente 2 fois la durée de vie maximale des segments de 120 secondes ou 4 minutes. Toutefois, vous pouvez utiliser cette entrée pour personnaliser l’intervalle.
La réduction de la valeur de cette entrée permet à TCP de libérer plus rapidement les connexions fermées, fournissant plus de ressources pour les nouvelles connexions. Toutefois, si la valeur est trop faible, TCP peut libérer des ressources de connexion avant la fin de la connexion, ce qui oblige le serveur à utiliser des ressources supplémentaires pour rétablir la connexion.
Ce paramètre de Registre peut être défini entre 0 et 300 secondes.
Windows Phone 8 : cette fonction est prise en charge pour les applications Windows Phone Store sur 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.
Configuration requise
Condition requise | Valeur |
---|---|
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 | mswsock.h |