Partager via


Fonction WSAAsyncSelect (winsock2.h)

[La fonction WSAAsyncSelect est disponible pour une utilisation dans les systèmes d’exploitation spécifiés dans la section Configuration requise. Il sera peut-être modifié ou indisponible dans les versions ultérieures. Au lieu d’utiliser les E/S de style Select, utilisez les objets d’E/S et d’événements qui se chevauchent avec WinSock2.]

La fonction WSAAsyncSelect demande une notification basée sur les messages Windows des événements réseau pour un socket.

Syntaxe

int WSAAPI WSAAsyncSelect(
  [in] SOCKET s,
  [in] HWND   hWnd,
  [in] u_int  wMsg,
  [in] long   lEvent
);

Paramètres

[in] s

Descripteur qui identifie le socket pour lequel une notification d’événement est requise.

[in] hWnd

Handle qui identifie la fenêtre qui recevra un message lorsqu’un événement réseau se produit.

[in] wMsg

Message à recevoir lorsqu’un événement réseau se produit.

[in] lEvent

Masque de bits qui spécifie une combinaison d’événements réseau qui intéressent l’application.

Valeur retournée

Si la fonction WSAAsyncSelect réussit, la valeur de retour est égale à zéro, à condition que la déclaration d’intérêt de l’application dans le jeu d’événements réseau ait réussi. Sinon, la valeur SOCKET_ERROR est retournée et un numéro d’erreur spécifique peut être récupéré en appelant WSAGetLastError.

Code d'erreur Signification
WSANOTINITIALISED
Un appel WSAStartup réussi doit se produire avant d’utiliser cette fonction.
WSAENETDOWN
Échec du sous-système réseau.
WSAEINVAL
L’un des paramètres spécifiés n’était pas valide, comme le handle de fenêtre ne faisant pas référence à une fenêtre existante, ou le socket spécifié n’est pas valide.
WSAEINPROGRESS
Un appel bloquant Windows Sockets 1.1 est en cours ou le fournisseur de services traite toujours une fonction de rappel.
WSAENOTSOCK
Le descripteur n’est pas un socket.
 

Des codes d’erreur supplémentaires peuvent être définis lorsqu’une fenêtre d’application reçoit un message. Ce code d’erreur est extrait de l’élément lParam dans le message de réponse à l’aide de la macro WSAGETSELECTERROR . Les codes d’erreur possibles pour chaque événement réseau sont répertoriés dans le tableau suivant.

Événement : FD_CONNECT

Code d'erreur Signification
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.
WSAENETUNREACH Le réseau ne peut pas être atteint à partir de cet hôte en ce moment.
WSAEFAULT Le paramètre namelen n’est pas valide.
WSAEINVAL Le socket est déjà lié à une adresse.
WSAEISCONN Le socket est déjà connecté.
WSAEMFILE Aucun autre descripteur de fichier n'est disponible.
WSAENOBUFS Aucune zone tampon disponible. Le socket ne peut pas être connecté.
WSAENOTCONN Le socket n'est pas connecté.
WSAETIMEDOUT La tentative de connexion a expiré sans établir de connexion.
 

Événement : FD_CLOSE

Code d'erreur Signification
WSAENETDOWN Échec du sous-système réseau.
WSAECONNRESET La connexion a été réinitialisée par le côté distant.
WSAECONNABORTED La connexion a été arrêtée en raison d’un délai d’attente ou d’un autre échec.
 
Code d'erreur Signification
WSAENETDOWN Échec du sous-système réseau.
 

Événement : FD_ROUTING_INTERFACE_CHANGE

Code d'erreur Signification
WSAENETUNREACH La destination spécifiée n’est plus accessible.
WSAENETDOWN Échec du sous-système réseau.

Remarques

La fonction WSAAsyncSelect permet de demander à WS2_32.DLL d’envoyer un message à la fenêtre hWnd lorsqu’il détecte un événement réseau spécifié par le paramètre lEvent . Le message qui doit être envoyé est spécifié par le paramètre wMsg . Le socket pour lequel une notification est requise est identifié par le paramètre s .

La fonction WSAAsyncSelect définit automatiquement les sockets en mode non bloquant, quelle que soit la valeur de lEvent. Pour revenir au mode de blocage des sockets, il est tout d’abord nécessaire d’effacer l’enregistrement d’événement associé aux sockets par le biais d’un appel à WSAAsyncSelect avec lEvent défini sur zéro. Vous pouvez ensuite appeler ioctlsocket ou WSAIoctl pour revenir au mode de blocage du socket. Pour plus d’informations sur la façon de remettre le socket non bloquant en mode bloquant, consultez les fonctions ioctlsocket et WSAIoctl .

Le paramètre lEvent est construit à l’aide de l’opérateur OR au niveau du bit avec n’importe quelle valeur répertoriée dans le tableau suivant.

Valeur Signification
FD_READ Défini pour recevoir une notification de préparation à la lecture.
FD_WRITE Souhaite recevoir une notification de préparation à la rédaction.
FD_OOB Souhaite recevoir une notification de l’arrivée des données OOB.
FD_ACCEPT Souhaite recevoir une notification des connexions entrantes.
FD_CONNECT Souhaite recevoir une notification de connexion ou d’opération de jointure multipoint terminée.
FD_CLOSE Souhaite recevoir une notification de fermeture du socket.
FD_QOS Souhaite recevoir une notification de modification de la qualité de service (QoS) du socket.
FD_GROUP_QOS Souhaite recevoir une notification concernant les modifications apportées à la qualité de service (QoS) du groupe de sockets (réservées pour une utilisation ultérieure avec des groupes de sockets). Réservé.
FD_ROUTING_INTERFACE_CHANGE Souhaite recevoir une notification des modifications apportées à l’interface de routage pour la ou les destinations spécifiées.
FD_ADDRESS_LIST_CHANGE Souhaite recevoir une notification des modifications apportées à la liste d’adresses locale pour la famille de protocoles de sockets.
 

L’émission d’un WSAAsyncSelect pour un socket annule tout WSAAsyncSelect ou WSAEventSelect précédent pour le même socket. Par exemple, pour recevoir une notification pour la lecture et l’écriture, l’application doit appeler WSAAsyncSelect avec FD_READ et FD_WRITE, comme suit :

rc = WSAAsyncSelect(s, hWnd, wMsg, FD_READ|FD_WRITE);

Il n’est pas possible de spécifier différents messages pour différents événements. Le code suivant ne fonctionnera pas ; le deuxième appel annule les effets du premier, et seuls les événements FD_WRITE sont signalés avec le message wMsg2 :

rc = WSAAsyncSelect(s, hWnd, wMsg1, FD_READ);
rc = WSAAsyncSelect(s, hWnd, wMsg2, FD_WRITE);

Pour annuler toute notification indiquant que windows Sockets ne doit envoyer aucun autre message lié aux événements réseau sur le socket, lEvent est défini sur zéro.

rc = WSAAsyncSelect(s, hWnd, 0, 0);

Bien que WSAAsyncSelect désactive immédiatement la publication des messages d’événement pour le socket dans ce instance, il est possible que les messages soient en attente dans la file d’attente des messages de l’application. Par conséquent, l’application doit être prête à recevoir des messages d’événement réseau, même après l’annulation. La fermeture d’un socket avec closesocket annule également l’envoi de messages WSAAsyncSelect , mais la même mise en garde concernant les messages dans la file d’attente s’applique toujours.

Le socket créé par la fonction accept a les mêmes propriétés que le socket d’écoute utilisé pour l’accepter. Par conséquent, les événements WSAAsyncSelect définis pour le socket d’écoute s’appliquent également au socket accepté. Par exemple, si un socket d’écoute a des événements WSAAsyncSelectFD_ACCEPT, FD_READ et FD_WRITE, tout socket accepté sur ce socket d’écoute aura également des événements FD_ACCEPT, FD_READ et FD_WRITE avec la même valeur wMsg utilisée pour les messages. Si un ou plusieurs événements wMsg différents sont souhaités, l’application doit appeler WSAAsyncSelect, en passant le socket accepté et les nouvelles données souhaitées.

Quand l’un des événements réseau nommés se produit sur les sockets spécifiés, la fenêtre d’application hWnd reçoit le message wMsg. Le paramètre wParam identifie le socket sur lequel un événement réseau s’est produit. Le mot bas de lParam spécifie l’événement réseau qui s’est produit. Le mot le plus élevé de lParam contient un code d’erreur. Le code d’erreur est toute erreur définie dans Winsock2.h.

Note À la réception d’un message de notification d’événement, la fonction WSAGetLastError ne peut pas être utilisée pour case activée la valeur d’erreur, car la valeur d’erreur retournée peut différer de la valeur dans le mot élevé de lParam.
 
Les codes d’erreur et d’événement peuvent être extraits de l’objet lParam à l’aide des macros WSAGETSELECTERROR et WSAGETSELECTEVENT, définies dans Winsock2.h comme suit :
#include <windows.h>

#define WSAGETSELECTEVENT(lParam)       LOWORD(lParam)
#define WSAGETSELECTERROR(lParam)       HIWORD(lParam)

L’utilisation de ces macros optimise la portabilité du code source pour l’application.

Les codes d’événement réseau possibles qui peuvent être retournés sont répertoriés dans le tableau suivant.

Valeur Signification
FD_READ Sockets prêts pour la lecture.
FD_WRITE Sockets prêts pour l’écriture.
FD_OOB Données OOB prêtes pour la lecture sur les sockets
FD_ACCEPT Sockets prêts pour accepter une nouvelle connexion entrante.
FD_CONNECT Opération de connexion ou de jointure multipoint lancée sur les sockets terminée.
FD_CLOSE La connexion identifiée par le socket s a été fermée.
FD_QOS La qualité de service associée au socket s a changé.
FD_GROUP_QOS Réservé. La qualité de service associée au groupe de sockets auquel appartient s a changé (réservée pour une utilisation ultérieure avec des groupes de sockets).
FD_ROUTING_INTERFACE_CHANGE L’interface locale qui doit être utilisée pour envoyer à la destination spécifiée a changé.
FD_ADDRESS_LIST_CHANGE La liste des adresses de la famille de protocoles de sockets à laquelle le client d’application peut lier a changé.
 

Bien que WSAAsyncSelect puisse être appelé avec intérêt pour plusieurs événements, la fenêtre d’application reçoit un seul message pour chaque événement réseau.

Comme dans le cas de la fonction select , WSAAsyncSelect est fréquemment utilisé pour déterminer quand une opération de transfert de données (envoi ou recv) peut être émise dans l’attente d’un succès immédiat. Néanmoins, une application robuste doit être préparée à la possibilité qu’elle puisse recevoir un message et émettre un appel Windows Sockets 2 qui retourne WSAEWOULDBLOCK immédiatement. Par exemple, la séquence d’événements suivante est possible :

  1. Les données arrivent sur les sockets ; Message WSAAsyncSelect pour Windows Sockets 2
  2. L’application traite un autre message
  3. Pendant le traitement, l’application émet un ioctlsocket(s, FIONREAD...) et remarque qu’il existe des données prêtes à être lues
  4. L’application émet un recv(s,...) pour lire les données
  5. L’application effectue une boucle pour traiter le message suivant, atteignant finalement le message WSAsyncSelect indiquant que les données sont prêtes à être lues
  6. Problèmes recv(s,...)d’application , qui échoue avec l’erreur WSAEWOULDBLOCK.
D’autres séquences sont également possibles.

Le WS2_32.DLL n’inonde pas continuellement une application de messages pour un événement réseau particulier. Une fois que la notification d’un événement particulier a été correctement publiée dans une fenêtre d’application, aucun autre message pour cet événement réseau n’est publié dans la fenêtre d’application jusqu’à ce que l’application effectue l’appel de fonction qui réactive implicitement la notification de cet événement réseau.

Événement Fonction de reenabling
FD_READ recv, recvfrom, WSARecv ou WSARecvFrom.
FD_WRITE send, sendto, WSASend ou WSASendTo.
FD_OOB recv, recvfrom, WSARecv ou WSARecvFrom.
FD_ACCEPT accept ou WSAAccept , sauf si le code d’erreur est WSATRY_AGAIN indiquant que la fonction condition a retourné CF_DEFER.
FD_CONNECT Aucun.
FD_CLOSE Aucun.
FD_QOS WSAIoctl avec commande SIO_GET_QOS.
FD_GROUP_QOS Réservé. WSAIoctl avec SIO_GET_GROUP_QOS de commande (réservé pour une utilisation ultérieure avec des groupes de sockets).
FD_ROUTING_INTERFACE_CHANGE WSAIoctl avec la commande SIO_ROUTING_INTERFACE_CHANGE.
FD_ADDRESS_LIST_CHANGE WSAIoctl avec SIO_ADDRESS_LIST_CHANGE de commande.
 

Tout appel à la routine de reenabling, même en cas d’échec, entraîne la réactivation de la publication de messages pour l’événement approprié.

Pour les événements FD_READ, FD_OOB et FD_ACCEPT , la publication de messages est déclenchée au niveau. Cela signifie que si la routine de réactivation est appelée et que la condition appropriée est toujours remplie après l’appel, un message WSAAsyncSelect est publié dans l’application. Cela permet à une application d’être pilotée par les événements et de ne pas se soucier de la quantité de données qui arrivent à un moment donné. Examinez la séquence suivante :

  1. La pile de transport réseau reçoit 100 octets de données sur les sockets et amène Windows Sockets 2 à publier un message FD_READ .
  2. L’application émet recv( s, buffptr, 50, 0) pour lire 50 octets.
  3. Un autre message FD_READ est publié, car il reste des données à lire.
Avec cette sémantique, une application n’a pas besoin de lire toutes les données disponibles en réponse à un message FD_READ : une seule recv en réponse à chaque message FD_READ est appropriée. Si une application émet plusieurs appels recv en réponse à une seule FD_READ, elle peut recevoir plusieurs messages FD_READ . Une telle application peut nécessiter la désactivation de FD_READ messages avant de démarrer les appels recv en appelant WSAAsyncSelect avec l’événement FD_READ non défini.

Les événements FD_QOS et FD_GROUP_QOS sont considérés comme déclenchés en périphérie. Un message est publié exactement une fois lorsqu’un changement de qualité de service se produit. D’autres messages ne seront pas envoyés tant que le fournisseur n’aura pas détecté une nouvelle modification de la qualité de service ou que l’application renégociera la qualité de service pour le socket.

Le message FD_ROUTING_INTERFACE_CHANGE est publié lorsque l’interface locale qui doit être utilisée pour atteindre la destination spécifiée dans WSAIoctl avec SIO_ROUTING_INTERFACE_CHANGE modifications après l’émission de ce type IOCTL.

Le message FD_ADDRESS_LIST_CHANGE est publié lorsque la liste des adresses auxquelles l’application peut se lier change après l’émission de WSAIoctl avec SIO_ADDRESS_LIST_CHANGE.

Si un événement s’est produit lorsque l’application appelle WSAAsyncSelect ou lorsque la fonction de réactivation est appelée, un message est publié comme il convient. Imaginons par exemple la séquence suivante :

  1. Une application appelle l’écoute.
  2. Une demande de connexion est reçue, mais pas encore acceptée.
  3. L’application appelle WSAAsyncSelect en spécifiant qu’elle doit recevoir FD_ACCEPT messages pour le socket. En raison de la persistance des événements, windows Sockets 2 publie immédiatement un message FD_ACCEPT .
L’événement FD_WRITE est géré légèrement différemment. Un message FD_WRITE est publié lorsqu’un socket est d’abord connecté avec connect ou WSAConnect (après FD_CONNECT, s’il est également inscrit) ou accepté avec accept ou WSAAccept, puis après l’échec d’une opération d’envoi avec WSAEWOULDBLOCK et que l’espace tampon est disponible. Par conséquent, une application peut supposer que les envois sont possibles à partir du premier message FD_WRITE et durent jusqu’à ce qu’un envoi retourne WSAEWOULDBLOCK. Après un tel échec, l’application est avertie que les envois sont à nouveau possibles avec un message FD_WRITE .

L’événement FD_OOB est utilisé uniquement lorsqu’un socket est configuré pour recevoir des données OOB séparément. Si le socket est configuré pour recevoir des données OOB inline, les données OOB (accélérées) sont traitées comme des données normales et l’application doit inscrire un intérêt pour les événements FD_READ et non FD_OOB . Une application peut définir ou inspecter la façon dont les données OOB doivent être gérées à l’aide de setsockopt ou getsockopt pour l’option SO_OOBINLINE.

Le code d’erreur d’un message FD_CLOSE indique si la fermeture du socket était normale ou abandonnée. Si le code d’erreur est égal à zéro, la fermeture était normale ; si le code d’erreur est WSAECONNRESET, le circuit virtuel du socket a été réinitialisé. Cela s’applique uniquement aux sockets orientés connexion tels que SOCK_STREAM.

Le message FD_CLOSE est publié lorsqu’une indication proche est reçue pour le circuit virtuel correspondant au socket. En termes TCP, cela signifie que l’FD_CLOSE est publié lorsque la connexion passe aux états TIME WAIT ou CLOSE WAIT. Cela résulte d’un arrêt de l’extrémité distante du côté de l’envoi ou d’un closesocket. FD_CLOSE ne doit être publié qu’après la lecture de toutes les données à partir d’un socket, mais une application doit case activée pour les données restantes à la réception de FD_CLOSE afin d’éviter toute perte de données.

N’oubliez pas que l’application ne reçoit qu’un message FD_CLOSE pour indiquer la fermeture d’un circuit virtuel, et uniquement lorsque toutes les données reçues ont été lues s’il s’agit d’une fermeture normale. Il ne recevra pas de message FD_READ pour indiquer cette condition.

Le message FD_QOS ou FD_GROUP_QOS est publié lorsqu’un paramètre de la spécification de flux associé au socket s ou au groupe de sockets auquel appartient a changé, respectivement. Les applications doivent utiliser WSAIoctl avec SIO_GET_QOS de commande ou SIO_GET_GROUP_QOS pour obtenir la qualité de service actuelle pour les sockets ou pour le groupe de sockets auquel appartient , respectivement.

Les événements FD_ROUTING_INTERFACE_CHANGE et FD_ADDRESS_LIST_CHANGE sont également considérés comme étant déclenchés. Un message est publié exactement une fois lorsqu’une modification se produit après que l’application a demandé la notification en émettant WSAIoctl avec SIO_ROUTING_INTERFACE_CHANGE ou SIO_ADDRESS_LIST_CHANGE correspondant. D’autres messages ne seront pas reçus tant que l’application n’aura pas réédité le IOCTL et qu’une autre modification n’aura pas été détectée, car le IOCTL n’a pas été émis.

Voici un résumé des événements et des conditions pour chaque message de notification asynchrone.

  • FD_READ :
    1. Lorsque WSAAsyncSelect est appelé, s’il existe des données actuellement disponibles à recevoir.
    2. Lorsque les données arrivent, si FD_READ n’est pas déjà publié.
    3. Une fois que recv ou recvfrom est appelé, avec ou sans MSG_PEEK), si les données sont toujours disponibles pour recevoir.
      Note Lorsque setsockopt SO_OOBINLINE est activé, les données incluent à la fois les données normales et les données OOB dans les instances indiquées ci-dessus.
       
  • FD_WRITE :
    1. Quand WSAAsyncSelect est appelé, si un envoi ou un envoi à est possible.
    2. Une fois la connexion ou l’acceptation appelée, lorsque la connexion est établie.
    3. Après l’échec de l’envoi ou de l’envoi àl’aide de WSAEWOULDBLOCK, lorsque l’envoi ou l’envoi à sont susceptibles de réussir.
    4. Après la liaison sur un socket sans connexion. FD_WRITE peut ou non se produire à ce stade (dépendant de l’implémentation). Dans tous les cas, un socket sans connexion est toujours accessible en écriture immédiatement après une opération de liaison .
  • FD_OOB : valide uniquement lorsque setsockopt SO_OOBINLINE est désactivé (par défaut).
    1. Lorsque WSAAsyncSelect est appelé, s’il existe des données OOB actuellement disponibles à recevoir avec l’indicateur MSG_OOB.
    2. Lorsque les données OOB arrivent, si FD_OOB pas déjà publiées.
    3. Après recv ou recvfrom appelé avec ou sans MSG_OOB indicateur, si les données OOB sont toujours disponibles pour recevoir.
  • FD_ACCEPT :
    1. Quand WSAAsyncSelect a appelé, s’il existe actuellement une demande de connexion disponible à accepter.
    2. Lorsqu’une demande de connexion arrive, si FD_ACCEPT pas déjà publié.
    3. Après l’acceptation appelée, s’il existe une autre demande de connexion disponible à accepter.
  • FD_CONNECT :
    1. Quand WSAAsyncSelect a appelé, s’il existe actuellement une connexion établie.
    2. Après l’appel de la connexion , lorsque la connexion est établie, même si la connexion réussit immédiatement, comme c’est généralement le cas avec un socket de datagramme.
    3. Après avoir appelé WSAJoinLeaf, une fois l’opération de jointure terminée.
    4. Après la connexion, WSAConnect ou WSAJoinLeaf a été appelé avec un socket non bloquant et orienté connexion. L’opération initiale retournée avec une erreur spécifique de WSAEWOULDBLOCK, mais l’opération réseau a été effectuée. Que l’opération aboutisse ou non, une fois le résultat déterminé, FD_CONNECT se produit. Le client doit case activée le code d’erreur pour déterminer si le résultat a réussi ou échoué.
  • FD_CLOSE : valide uniquement sur les sockets orientés connexion (par exemple, SOCK_STREAM)
    1. Lorsque WSAAsyncSelect a été appelé, si la connexion de socket a été fermée.
    2. Une fois que le système distant a lancé la fermeture normale, lorsqu’aucune donnée n’est actuellement disponible pour recevoir (Sachez que, si des données ont été reçues et attendent d’être lues lorsque le système distant lance une fermeture normale, le FD_CLOSE n’est pas remis tant que toutes les données en attente n’ont pas été lues).
    3. Une fois que le système local a lancé une fermeture normale avec arrêt et que le système distant a répondu avec la notification « Fin des données » (par exemple, TCP FIN), lorsqu’aucune donnée actuellement disponible à recevoir.
    4. Lorsque le système distant arrête la connexion (par exemple, tcp RST envoyé) et que lParam contient la valeur d’erreur WSAECONNRESET .
      NotezFD_CLOSE n’est pas publié après l’appel de closesocket .
       
  • FD_QOS :
    1. Lorsque WSAAsyncSelect a été appelé, si la qualité de service associée au socket a été modifiée.
    2. Après WSAIoctl avec SIO_GET_QOS appelé, lorsque la qualité du service est modifiée.
  • FD_GROUP_QOS : réservé.
  • FD_ROUTING_INTERFACE_CHANGE :
    • Après WSAIoctl avec SIO_ROUTING_INTERFACE_CHANGE appelé, lorsque l’interface locale qui doit être utilisée pour atteindre la destination spécifiée dans le IOCTL change.
  • FD_ADDRESS_LIST_CHANGE :
    • Après WSAIoctl avec SIO_ADDRESS_LIST_CHANGE appelé, lorsque la liste des adresses locales auxquelles l’application peut lier change.

Configuration requise

Condition requise Valeur
Client minimal pris en charge Windows 2000 Professionnel [applications de bureau uniquement]
Serveur minimal pris en charge Windows 2000 Server [applications de bureau uniquement]
Plateforme cible Windows
En-tête winsock2.h (inclure Winsock2.h)
Bibliothèque Ws2_32.lib
DLL Ws2_32.dll

Voir aussi

WSAEventSelect

Fonctions Winsock

Informations de référence sur Winsock

select