Partager via


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.

Note Cette fonction est une extension spécifique à Microsoft de la spécification Windows Sockets.

 

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
WSANOTINITIALISED
Un appel de fonction WSAStartup réussi doit se produire avant d’utiliser ConnectEx.
WSAENETDOWN
Le sous-système réseau a échoué.
WSAEADDRINUSE
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 .
WSAEALREADY
Un appel de fonction connect, WSAConnect ou ConnectEx sans blocage est en cours sur le socket spécifié.
WSAEADDRNOTAVAIL
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).
WSAEAFNOSUPPORT
Impossible d'utiliser les adresses figurant dans la famille spécifiée avec ce socket.
WSAECONNREFUSED
La tentative de connexion a été rejetée.
WSAEFAULT
Le paramètre name, lpSendBuffer ou lpOverlapped n’est pas une partie valide de l’espace d’adressage utilisateur, ou namelen est trop petit.
WSAEINVAL
Le paramètre s est un socket indépendant ou d’écoute.
WSAEISCONN
Le socket est déjà connecté.
WSAENETUNREACH
Le réseau ne peut pas être atteint à partir de cet hôte en ce moment.
WSAEHOSTUNREACH
Une opération de socket a été tentée sur un hôte impossible à atteindre.
WSAENOBUFS
Aucun espace de mémoire tampon n’est disponible ; le socket ne peut pas être connecté.
WSAENOTSOCK
Le descripteur n’est pas un socket.
WSAETIMEDOUT
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 .

Note Le pointeur de fonction pour la fonction ConnectEx doit être obtenu au moment de l’exécution en effectuant un appel à la fonction WSAIoctl avec l’opcode SIO_GET_EXTENSION_FUNCTION_POINTER spécifié. La mémoire tampon d’entrée passée à la fonction WSAIoctl doit contenir WSAID_CONNECTEX, un identificateur global unique (GUID) dont la valeur identifie la fonction d’extension ConnectEx . En cas de réussite, la sortie retournée par la fonction WSAIoctl contient un pointeur vers la fonction ConnectEx . Le GUID WSAID_CONNECTEX est défini dans le fichier d’en-tête Mswsock.h .
 

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.

Note Toutes les E/S initiées par un thread donné sont annulées lorsque ce thread se ferme. Pour les sockets qui se chevauchent, les opérations asynchrones en attente peuvent échouer si le thread est fermé avant la fin des opérations. Pour plus d’informations, consultez ExitThread .

 

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

Note Si un socket est ouvert, un appel setsockopt est effectué, puis un appel sendto est effectué, Windows Sockets effectue un appel de fonction de liaison implicite.
 

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

Voir aussi

AcceptEx

DisconnectEx

ExitThread

GetOverlappedResult

GetQueuedCompletionStatus

OVERLAPPED

ReadFile

TransmitFile

WSAConnect

WSAConnectByList

WSAConnectByName

WSAGetLastError

WSAIoctl

WSARecv

WSASend

WSAStartup

Winsock Functions

Référence Winsock

WriteFile

bind

closesocket

connect

getsockopt

Recv

envoyer

Sendto

setsockopt

sockaddr