Fonction WSAEventSelect (winsock2.h)
La fonction WSAEventSelect spécifie un objet d’événement à associer au jeu d’événements réseau FD_XXX spécifié.
Syntaxe
int WSAAPI WSAEventSelect(
[in] SOCKET s,
[in] WSAEVENT hEventObject,
[in] long lNetworkEvents
);
Paramètres
[in] s
Descripteur identifiant le socket.
[in] hEventObject
Handle identifiant l’objet d’événement à associer au jeu spécifié d’événements réseau FD_XXX.
[in] lNetworkEvents
Masque de bits qui spécifie la combinaison d’événements réseau FD_XXX qui intéressent l’application.
Valeur retournée
La valeur de retour est zéro si la spécification par l’application des événements réseau et de l’objet d’événement associé a 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.
Comme dans le cas des fonctions select et WSAAsyncSelect , WSAEventSelect 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 pour la possibilité que l’objet d’événement soit défini et qu’elle émet un appel Windows Sockets qui retourne WSAEWOULDBLOCK immédiatement. Par exemple, la séquence d’opérations suivante est possible :
- Les données arrivent sur les sockets ; Windows Sockets définit l’objet d’événement WSAEventSelect .
- L’application effectue d’autres traitements.
- Pendant le traitement, l’application émet un(s) ioctlsocket(s, FIONREAD...) et remarque que des données sont prêtes à être lues.
- L’application émet un ou plusieurs recv(s,...) pour lire les données.
- L’application attend finalement l’objet d’événement spécifié dans WSAEventSelect, qui retourne immédiatement indiquant que les données sont prêtes à être lues.
- L’application émet recv(s,...), ce qui échoue avec l’erreur WSAEWOULDBLOCK.
Événement réseau | Réactiver la fonction |
---|---|
|
Fonction recv, recvfrom, WSARecv, WSARecvEx ou WSARecvFrom . |
|
Fonction send, sendto, WSASend ou WSASendTo . |
|
Fonction recv, recvfrom, WSARecv, WSARecvEx ou WSARecvFrom . |
|
La fonction accept, AcceptEx ou WSAAccept , sauf si le code d’erreur retourné est WSATRY_AGAIN indiquant que la fonction condition a retourné CF_DEFER. |
|
Aucun. |
|
Aucun. |
|
Fonction WSAIoctl avec commande SIO_GET_QOS. |
|
Réservé. |
|
Fonction WSAIoctl avec commande SIO_ROUTING_INTERFACE_CHANGE. |
|
Fonction WSAIoctl avec commande SIO_ADDRESS_LIST_CHANGE. |
Tout appel à la routine de reenabling, même en cas d’échec, entraîne la réactivation de l’enregistrement et de la signalisation pour l’événement réseau et l’objet d’événement appropriés.
Pour les événements réseau FD_READ, FD_OOB et FD_ACCEPT, l’enregistrement des événements réseau et la signalisation des objets d’événement sont déclenchés au niveau. Cela signifie que si la routine de réactivation est appelée et que la condition réseau appropriée est toujours valide après l’appel, l’événement réseau est enregistré et l’objet d’événement associé est défini. 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 :
- Le fournisseur de transport reçoit 100 octets de données sur les sockets et WS2_32.DLL enregistre l’événement réseau FD_READ et définit l’objet d’événement associé.
- L’application émet recv(s, buffptr, 50, 0) pour lire 50 octets.
- Le fournisseur de transport entraîne WS2_32.DLL à enregistrer l’événement réseau FD_READ et définit à nouveau l’objet d’événement associé, car il reste des données à lire.
L’événement FD_QOS est considéré comme étant déclenché par la périphérie. Un message est publié exactement une fois lorsqu’une modification de la 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égocie la qualité de service du socket.
Les événements FD_ROUTING_INTERFACE_CHANGE et FD_ADDRESS_LIST_CHANGE sont également considérés comme déclenchés par la périphérie. 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 envoyés tant que l’application n’aura pas réédité l’IOCTL et qu’une autre modification est détectée depuis que l’IOCTL a été émis.
Si un événement réseau s’est déjà produit lorsque l’application appelle WSAEventSelect ou lorsque la fonction de reenabling est appelée, un événement réseau est enregistré et l’objet d’événement associé est défini comme il convient. Imaginons par exemple la séquence suivante :
- Une application appelle listen.
- Une demande de connexion est reçue, mais n’est pas encore acceptée.
- L’application appelle WSAEventSelect en spécifiant qu’elle est intéressée par l’événement réseau FD_ACCEPT pour le socket. En raison de la persistance des événements réseau, Windows Sockets enregistre l’événement réseau FD_ACCEPT et définit immédiatement l’objet d’événement associé.
L’événement réseau 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 et obtenir FD_READ événement réseau, et non FD_OOB événement réseau. 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 événement réseau FD_CLOSE indique si la fermeture du socket a été 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.
L’événement réseau FD_CLOSE est enregistré lorsqu’une indication de fermeture est reçue pour le circuit virtuel correspondant au socket. En termes TCP, cela signifie que le FD_CLOSE est enregistré lorsque la connexion passe aux états TIME WAIT ou CLOSE WAIT. Cela résulte du fait que la terminaison distante effectue un arrêt côté envoi ou un closesocket. FD_CLOSE en cours de publication après la lecture de toutes les données à partir d’un socket. Une application doit case activée pour les données restantes à la réception de FD_CLOSE afin d’éviter toute possibilité de perte de données. Pour plus d’informations, consultez la section sur l’arrêt normal, les options persistantes et la fermeture de socket et la fonction d’arrêt .
Notez que Windows Sockets enregistre uniquement un événement réseau FD_CLOSE pour indiquer la fermeture d’un circuit virtuel. Il n’enregistre pas d’événement réseau FD_READ pour indiquer cette condition.
L’événement réseau FD_QOS ou FD_GROUP_QOS est enregistré lorsqu’un paramètre dans la spécification de flux associée à des sockets. Les applications doivent utiliser WSAIoctl avec la commande SIO_GET_QOS pour obtenir la qualité de service actuelle pour les sockets.
L’événement réseau FD_ROUTING_INTERFACE_CHANGE est enregistré 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.
L’événement réseau FD_ADDRESS_LIST_CHANGE est enregistré lorsque la liste des adresses de la famille de protocoles pour le socket auquel l’application peut lier des modifications après l’émission de WSAIoctl avec SIO_ADDRESS_LIST_CHANGE .
Code d'erreur | Signification |
---|---|
WSANOTINITIALISED | Un appel WSAStartup réussi doit se produire avant d’utiliser cette fonction. |
WSAENETDOWN | Le sous-système réseau a échoué. |
WSAEINVAL | L’un des paramètres spécifiés n’était pas valide ou le socket spécifié est dans un état non valide. |
WSAEINPROGRESS | Un appel Windows Sockets 1.1 bloquant est en cours ou le fournisseur de services traite toujours une fonction de rappel. |
WSAENOTSOCK | Le descripteur n’est pas un socket. |
Remarques
La fonction WSAEventSelect permet de spécifier un objet d’événement, hEventObject, à associer aux événements réseau FD_XXX sélectionnés, lNetworkEvents. Le socket pour lequel un objet d’événement est spécifié est identifié par le paramètre s . L’objet événement est défini quand l’un des événements réseau nommés se produit.
La fonction WSAEventSelect fonctionne de manière très similaire à WSAsyncSelect, la différence étant les actions effectuées lorsqu’un événement réseau nommé se produit. La fonction WSAAsyncSelect entraîne la publication d’un message Windows spécifié par l’application. WSAEventSelect définit l’objet d’événement associé et enregistre l’occurrence de cet événement dans un enregistrement d’événement réseau interne. Une application peut utiliser WSAWaitForMultipleEvents pour attendre ou interroger l’objet d’événement, et utiliser WSAEnumNetworkEvents pour récupérer le contenu de l’enregistrement d’événement réseau interne et ainsi déterminer quels événements réseau nommés ont eu lieu.
La façon appropriée de réinitialiser l’état d’un objet événement utilisé avec la fonction WSAEventSelect consiste à passer le handle de l’objet d’événement à la fonction WSAEnumNetworkEvents dans le paramètre hEventObject . Cela réinitialise l’objet d’événement et ajuste la status des événements FD actifs sur le socket de manière atomique.
WSAEventSelect est la seule fonction qui entraîne l’enregistrement et la récupération de l’activité réseau et des erreurs via WSAEnumNetworkEvents. Consultez les descriptions de select et WSAAsyncSelect pour savoir comment ces fonctions signalent l’activité du réseau et les erreurs.
La fonction WSAEventSelect définit automatiquement les sockets en mode sans blocage, quelle que soit la valeur de lNetworkEvents. Pour que les sockets reviennent en mode bloquant, il est tout d’abord nécessaire d’effacer l’enregistrement d’événement associé aux sockets via un appel à WSAEventSelect avec lNetworkEvents défini sur zéro et le paramètre hEventObject défini sur NULL. Vous pouvez ensuite appeler ioctlsocket ou WSAIoctl pour remettre le socket en mode bloquant.
Le paramètre lNetworkEvents est construit à l’aide de l’opérateur OR au niveau du bit avec l’une des valeurs spécifiées dans la liste suivante.
Valeur | Signification |
---|---|
FD_READ | Souhaite recevoir une notification de préparation à la lecture. |
FD_WRITE | Souhaite recevoir une notification de préparation à l’écriture. |
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 terminée ou d’opération de jointure multipoint. |
FD_CLOSE | Souhaite recevoir une notification de fermeture de socket. |
FD_QOS | Souhaite recevoir une notification de socket (modifications de QoS. |
FD_GROUP_QOS | Réservé pour une utilisation ultérieure avec des groupes de sockets. Vous souhaitez recevoir une notification des modifications qoS du groupe de sockets. |
FD_ROUTING_ INTERFACE_CHANGE | Souhaite recevoir une notification des modifications apportées à l’interface de routage pour la destination spécifiée. |
FD_ADDRESS_ LIST_CHANGE | Souhaite recevoir une notification des modifications apportées à la liste d’adresses locale pour la famille d’adresses du socket. |
L’émission d’un WSAEventSelect pour un socket annule tout WSAAsyncSelect ou WSAEventSelect précédent pour le même socket et efface l’enregistrement d’événement réseau interne. Par exemple, pour associer un objet événement à des événements réseau de lecture et d’écriture, l’application doit appeler WSAEventSelect avec FD_READ et FD_WRITE, comme suit :
rc = WSAEventSelect(s, hEventObject, FD_READ|FD_WRITE);
Il n’est pas possible de spécifier différents objets d’événement pour différents événements réseau. Le code suivant ne fonctionnera pas ; le deuxième appel annule les effets du premier, et seul l’événement réseau FD_WRITE est associé à hEventObject2 :
rc = WSAEventSelect(s, hEventObject1, FD_READ);
rc = WSAEventSelect(s, hEventObject2, FD_WRITE); //bad
Pour annuler l’association et la sélection d’événements réseau sur un socket, lNetworkEvents doit être défini sur zéro, auquel cas le paramètre hEventObject est ignoré.
rc = WSAEventSelect(s, hEventObject, 0);
La fermeture d’un socket avec closesocket annule également l’association et la sélection des événements réseau spécifiés dans WSAEventSelect pour le socket. Toutefois, l’application doit toujours appeler WSACloseEvent pour fermer explicitement l’objet d’événement et libérer toutes les ressources.
Le socket créé lorsque la fonction accept est appelée a les mêmes propriétés que le socket d’écoute utilisé pour l’accepter. Tout jeu de sélection d’événements réseau et d’association WSAEventSelect pour le socket d’écoute s’applique au socket accepté. Par exemple, si un socket d’écoute a une association WSAEventSelect de hEventObject avec FD_ACCEPT, FD_READ et FD_WRITE, tout socket accepté sur ce socket d’écoute aura également FD_ACCEPT, FD_READ et FD_WRITE événements réseau associés au même hEventObject. Si un autre hEventObject ou des événements réseau sont souhaités, l’application doit appeler WSAEventSelect, en passant le socket accepté et les nouvelles informations souhaitées.
Exemple de code
L’exemple suivant illustre l’utilisation de la fonction WSAEventSelect .//-------------------------
// Declare and initialize variables
SOCKET ListenSocket;
WSAEVENT NewEvent;
sockaddr_in InetAddr;
//-------------------------
// Initialize listening socket
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//-------------------------
// Bind listening socket
InetAddr.sin_family = AF_INET;
InetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InetAddr.sin_port = htons(27015);
bind (ListenSocket, (SOCKADDR *) &InetAddr, sizeof(InetAddr));
//-------------------------
// Create new event
NewEvent = WSACreateEvent();
//-------------------------
// Associate event types FD_ACCEPT and FD_CLOSE
// with the listening socket and NewEvent
WSAEventSelect( ListenSocket, NewEvent, FD_ACCEPT | FD_CLOSE);
//----------------------
// Listen for incoming connection requests
// on the created socket
if (listen( ListenSocket, SOMAXCONN ) == SOCKET_ERROR)
printf("Error listening on socket.\n");
printf("Listening on socket...\n");
// Need an event handler added to handle connection requests
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 | winsock2.h |
Bibliothèque | Ws2_32.lib |
DLL | Ws2_32.dll |