Fonction de rappel LPWSPRECV (ws2spi.h)

La fonction LPWSPRecv reçoit des données sur un socket.

Syntaxe

LPWSPRECV Lpwsprecv;

int Lpwsprecv(
  [in]         SOCKET s,
  \[in\, out\] LPWSABUF lpBuffers,
  [in]         DWORD dwBufferCount,
  [out]        LPDWORD lpNumberOfBytesRecvd,
  \[in\, out\] LPDWORD lpFlags,
  [in]         LPWSAOVERLAPPED lpOverlapped,
  [in]         LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  [in]         LPWSATHREADID lpThreadId,
  [out]        LPINT lpErrno
)
{...}

Paramètres

[in] s

Descripteur identifiant un socket connecté.

\\[in\\, out\\] lpBuffers

Pointeur vers un tableau de structures WSABUF . Chaque structure WSABUF contient un pointeur vers une mémoire tampon et la longueur de la mémoire tampon, en octets.

[in] dwBufferCount

Nombre de structures WSABUF dans le tableau lpBuffers .

[out] lpNumberOfBytesRecvd

Pointeur vers le nombre d’octets reçus par cet appel.

\\[in\\, out\\] lpFlags

Pointeur vers des indicateurs qui spécifient la façon dont l’appel est effectué.

[in] lpOverlapped

Pointeur vers une structure WSAOverlapped (ignoré pour les structures non survolées).

[in] lpCompletionRoutine

Type : _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE

Pointeur vers la routine d’achèvement appelée lorsque l’opération de réception est terminée (ignoré pour les structures non survolées).

[in] lpThreadId

Pointeur vers une structure WSATHREADID à utiliser par le fournisseur dans un appel ultérieur à WPUQueueApc. Le fournisseur doit stocker la structure WSATHREADID référencée (pas le pointeur vers le même) jusqu’à ce que la fonction WPUQueueApc soit retournée.

[out] lpErrno

Pointeur vers le code d’erreur.

Valeur retournée

Si aucune erreur ne se produit et que l’opération de réception est terminée immédiatement, LPWSPRecv retourne zéro. Notez que dans ce cas, la routine d’achèvement, si elle est spécifiée, aura déjà été mise en file d’attente. Sinon, une valeur de SOCKET_ERROR est retournée et un code d’erreur spécifique est disponible dans lpErrno. Le code d’erreur WSA_IO_PENDING indique que l’opération qui se chevauche a été lancée avec succès et que l’achèvement sera indiqué ultérieurement. Tout autre code d’erreur indique qu’aucune opération qui se chevauche n’a été lancée et qu’aucune indication d’achèvement ne se produira.

Code d'erreur Signification
WSAENETDOWN
Le sous-système réseau a échoué.
WSAENOTCONN
Le socket n'est pas connecté.
WSAEINTR
L’appel (bloquant) a été annulé via LPWSPCancelBlockingCall.
WSAEINPROGRESS
L’appel de sockets Windows est en cours ou le fournisseur de services traite toujours une fonction de rappel.
WSAENETRESET
La connexion a été interrompue, car l'activité persistante a détecté un échec en cours d'opération.
WSAEFAULT
Le paramètre lpBuffers n’est pas totalement contenu dans une partie valide de l’espace d’adressage utilisateur.
WSAENOTSOCK
Le descripteur n’est pas un socket.
WSAEOPNOTSUPP
MSG_OOB a été spécifié, mais le socket n’est pas de type flux tel que le type SOCK_STREAM, les données OOB ne sont pas prises en charge dans le domaine de communication associé à ce socket, ou le socket est unidirectionnel et prend uniquement en charge les opérations d’envoi.
WSAESHUTDOWN
Le socket a été arrêté ; il n’est pas possible de recevoir via LPWSPRecv sur un socket une fois que LPWSPShutdown a été appelé avec la valeur définie sur SD_RECEIVE ou SD_BOTH.
WSAEWOULDBLOCK
Windows NT : sockets superposés : il y a trop de demandes d’E/S qui se chevauchent. Sockets non bloqués : le socket est marqué comme non bloquant et l’opération de réception ne peut pas être effectuée immédiatement.
WSAEMSGSIZE
Le message était trop volumineux pour tenir dans la mémoire tampon spécifiée et (pour les protocoles non fiables uniquement) toute partie de fin du message qui ne correspondait pas à la mémoire tampon a été ignorée.
WSAEINVAL
Le socket n’a pas été lié (par exemple, avec LPWSPBind) ou le socket n’est pas créé avec l’indicateur qui se chevauche.
WSAECONNABORTED
Le circuit virtuel a été arrêté en raison d’un délai d’attente ou d’une autre défaillance.
WSAECONNRESET
Le circuit virtuel a été réinitialisé par le côté distant.
WSAEDISCON
Le socket s est orienté message et le circuit virtuel a été correctement fermé par le côté distant.
WSA_IO_PENDING
Une opération qui se chevauche a été lancée avec succès et l’achèvement sera indiqué ultérieurement.
WSA_OPERATION_ABORTED
L’opération qui se chevauche a été annulée en raison de la fermeture du socket.

Remarques

LPWSPRecv est utilisé sur les sockets connectés ou les sockets sans connexion liés spécifiés par le paramètre s et est utilisé pour lire les données entrantes. L’adresse locale du socket doit être connue. Cela peut être effectué explicitement via LPWSPBind ou implicitement via LPWSPAccept, LPWSPConnect, LPWSPSendTo ou LPWSPJoinLeaf.

Pour les sockets connectés sans connexion, cette fonction limite les adresses à partir desquelles les messages reçus sont acceptés. La fonction retourne uniquement les messages de l’adresse distante spécifiée dans la connexion. Les messages provenant d’autres adresses sont (en mode silencieux) ignorés.

Pour les sockets qui se chevauchent, LPWSPRecv est utilisé pour publier une ou plusieurs mémoires tampons dans lesquelles les données entrantes seront placées à mesure qu’elles seront disponibles, après quoi l’indication d’achèvement spi des sockets Windows (appel de la routine d’achèvement ou du paramètre d’un objet d’événement) se produit. Si l’opération ne se termine pas immédiatement, la status d’achèvement finale est récupérée via la routine d’achèvement ou LPWSPGetOverlappedResult.

Si lpOverlapped et lpCompletionRoutine sont tous deux null, le socket dans cette fonction est traité comme un socket nonoverlapped.

Pour les sockets nonoverlapped, les paramètres lpOverlapped, lpCompletionRoutine et lpThreadId sont ignorés. Toutes les données qui ont déjà été reçues et mises en mémoire tampon par le transport seront copiées dans les mémoires tampons utilisateur fournies. Dans le cas d’un socket bloquant sans qu’aucune donnée n’ait été reçue et mise en mémoire tampon par le transport, l’appel sera bloqué jusqu’à ce que les données soient reçues. Windows Sockets 2 ne définit pas de mécanisme de délai d’attente de blocage standard pour cette fonction. Pour les protocoles agissant en tant que protocoles de flux d’octets, la pile tente de retourner autant de données que possible sous réserve de l’espace tampon fourni et de la quantité de données reçues disponibles. Toutefois, la réception d’un seul octet est suffisante pour débloquer l’appelant. Il n’existe aucune garantie que plusieurs octets seront retournés. Pour les protocoles orientés message, un message complet est nécessaire pour débloquer l’appelant.

Le fait qu’un protocole agisse ou non en tant que flux d’octets est déterminé par le paramètre de XP1_MESSAGE_ORIENTED et XP1_PSEUDO_STREAM dans sa structure de WSAPROTOCOL_INFO et le paramètre de l’indicateur MSG_PARTIAL passé à cette fonction (pour les protocoles qui la prennent en charge). Les combinaisons pertinentes sont résumées dans le tableau suivant (un astérisque (*) indique que le paramètre de ce bit n’a pas d’importance dans ce cas).

XP1_MESSAGE_ORIENTED XP1_PSEUDO_STREAM MSG_PARTIAL Agit en tant que
non défini * * flux d’octets
* set * flux d’octets
set non défini set flux d’octets
set non défini non défini orienté message

Les mémoires tampons fournies sont remplies dans l’ordre dans lequel elles apparaissent dans le tableau pointé par lpBuffers, et les tampons sont emballés de sorte qu’aucun trou n’est créé.

Le tableau de structures WSABUF pointées vers le paramètre lpBuffers est temporaire. Si cette opération se termine de manière chevauchée, il incombe au fournisseur de services de capturer ce tableau de pointeurs vers les structures WSABUF avant de revenir à partir de cet appel. Cela permet aux clients SPI Windows Sockets de créer des tableaux WSABUF basés sur une pile.

Pour les sockets de type flux d’octets (par exemple, type SOCK_STREAM), les données entrantes sont placées dans les mémoires tampons jusqu’à ce que les mémoires tampons soient remplies, que la connexion soit fermée ou que les données mises en mémoire tampon en interne soient épuisées. Que les données entrantes remplissent ou non toutes les mémoires tampons, l’indication d’achèvement se produit pour les sockets qui se chevauchent. Pour les sockets orientés messages (par exemple, type SOCK_DGRAM), un message entrant est placé dans les mémoires tampons fournies, jusqu’à la taille totale des mémoires tampons fournies, et l’indication d’achèvement se produit pour les sockets superposés. Si le message est plus grand que les mémoires tampons fournies, les mémoires tampons sont remplies avec la première partie du message. Si la fonctionnalité MSG_PARTIAL est prise en charge par le fournisseur de services, l’indicateur MSG_PARTIAL est défini dans lpFlags et les opérations de réception suivantes peuvent être utilisées pour récupérer le reste du message. Si MSG_PARTIAL n’est pas pris en charge mais que le protocole est fiable, LPWSPRecv génère l’erreur WSAEMSGSIZE et une opération de réception ultérieure avec une mémoire tampon plus grande peut être utilisée pour récupérer l’intégralité du message. Sinon, (autrement dit, le protocole n’est pas fiable et ne prend pas en charge les MSG_PARTIAL), les données excédentaires sont perdues et LPWSPRecv génère l’erreur WSAEMSGSIZE.

Pour les sockets orientés connexion, LPWSPRecv peut indiquer l’arrêt normal du circuit virtuel de deux manières, selon que le socket est un flux d’octets ou un message orienté. Pour les flux d’octets, zéro octet ayant été lu indique une fermeture normale et qu’aucun autre octet ne sera lu. Pour les sockets orientés message, où un message de zéro octet est souvent autorisé, un code d’erreur de retour WSAEDISCON est utilisé pour indiquer une fermeture normale. Dans tous les cas, un code d’erreur de retour de WSAECONNRESET indique qu’une fermeture abandonnée s’est produite.

Le paramètre lpFlags peut être utilisé pour influencer le comportement de l’appel de fonction au-delà des options spécifiées pour le socket associé. Autrement dit, la sémantique de cette fonction est déterminée par les options de socket et le paramètre lpFlags . Ce dernier est construit à l’aide de l’opérateur OR au niveau du bit avec l’une des valeurs suivantes.

Valeur Signification
MSG_PEEK Jetez un coup d’œil aux données entrantes. Les données sont copiées dans la mémoire tampon, mais ne sont pas supprimées de la file d’attente d’entrée. Cet indicateur est valide uniquement pour les sockets non inexploités.
MSG_OOB Traite les données hors bande (OOB).
MSG_PARTIAL Cet indicateur concerne uniquement les sockets orientés message. En sortie, indique que les données fournies sont une partie du message transmis par l’expéditeur. Les parties restantes du message seront fournies lors des opérations de réception suivantes. Une opération de réception ultérieure avec MSG_PARTIAL indicateur effacé indique la fin du message de l’expéditeur. En tant que paramètre d’entrée, MSG_PARTIAL indique que l’opération de réception doit se terminer même si seule une partie d’un message a été reçue par le fournisseur de services.

Si une opération qui se chevauche se termine immédiatement, LPWSPRecv retourne une valeur de zéro et le paramètre lpNumberOfBytesRecvd est mis à jour avec le nombre d’octets reçus et les bits d’indicateur pointés par le paramètre lpFlags sont également mis à jour. Si l’opération qui se chevauche est correctement lancée et se terminera ultérieurement, LPWSPRecv retourne SOCKET_ERROR et indique le code d’erreur WSA_IO_PENDING. Dans ce cas, lpNumberOfBytesRecvd et lpFlags ne sont pas mis à jour. Lorsque l’opération qui se chevauche se termine, la quantité de données transférées est indiquée par le biais du paramètre cbTransferred dans la routine d’achèvement (si spécifié), ou via le paramètre lpcbTransfer dans LPWWSPGetOverlappedResult. Les valeurs d’indicateur sont obtenues par le biais du paramètre dwFlags de la routine d’achèvement, ou en examinant le paramètre lpdwFlags de WSAGetOverlappedResult.

Les fournisseurs doivent autoriser l’appel de cette fonction à partir de la routine d’achèvement d’une fonction LPWSPRecv, LPWSPRecvFrom, LPWSPSend ou LPWSPSendTo précédente. Toutefois, pour un socket donné, les routines d’achèvement d’E/S ne peuvent pas être imbriquées. Cela permet aux transmissions de données sensibles au temps de se produire entièrement dans un contexte préemptif.

Le paramètre lpOverlapped doit être valide pendant la durée de l’opération qui se chevauche. Si plusieurs opérations d’E/S sont simultanément en attente, chacune doit faire référence à une structure distincte qui se chevauche. La structure WSAOverlapped est définie dans sa propre page de référence.

Si le paramètre lpCompletionRoutine est null, le fournisseur de services signale le membre hEvent de lpOverlapped lorsque l’opération qui se chevauche se termine s’il contient un handle d’objet d’événement valide. Le client SPI Windows Sockets peut utiliser LPWSPGetOverlappedResult pour attendre ou interroger l’objet d’événement.

Si lpCompletionRoutine n’est pas null, le membre hEvent est ignoré et peut être utilisé par le client SPI Windows Sockets pour transmettre des informations de contexte à la routine d’achèvement. Un client qui transmet une valeur null lpCompletionRoutine et appelle ultérieurement WSAGetOverlappedResult pour la même demande d’E/S superposée ne peut pas définir le paramètre fWait pour cet appel de WSAGetOverlappedResult sur TRUE. Dans ce cas, l’utilisation du membre hEvent n’est pas définie et une tentative d’attente sur le membre hEvent produit des résultats imprévisibles.

Il incombe au fournisseur de services d’organiser l’appel de la routine d’achèvement spécifiée par le client lorsque l’opération qui se chevauche se termine. Étant donné que la routine d’achèvement doit être exécutée dans le contexte du même thread que celui qui a lancé l’opération superposée, elle ne peut pas être appelée directement à partir du fournisseur de services. Le Ws2_32.dll offre un mécanisme d’appel de procédure asynchrone (APC) pour faciliter l’appel des routines d’achèvement.

Un fournisseur de services organise l’exécution d’une fonction dans le contexte de thread et de processus appropriés en appelant WPUQueueApc, qui a été utilisé pour lancer l’opération chevauchée. Cette fonction peut être appelée à partir de n’importe quel contexte de processus et de thread, même dans un contexte différent du thread et du processus utilisé pour lancer l’opération qui se chevauche.

WPUQueueApc prend comme paramètres d’entrée un pointeur vers une structure WSATHREADID (fournie au fournisseur via le paramètre d’entrée lpThreadId ), un pointeur vers une fonction APC à appeler et une valeur de contexte qui est ensuite passée à la fonction APC. Étant donné qu’une seule valeur de contexte est disponible, la fonction APC elle-même ne peut pas être la routine d’achèvement spécifiée par le client. Le fournisseur de services doit à la place fournir un pointeur vers sa propre fonction APC qui utilise la valeur de contexte fournie pour accéder aux informations de résultat nécessaires pour l’opération qui se chevauche, puis appelle la routine d’achèvement spécifiée par le client.

Le prototype de la routine d’achèvement fournie par le client est le suivant.

void CALLBACK 
CompletionRoutine(  
  IN DWORD           dwError, 
  IN DWORD           cbTransferred, 
  IN LPWSAOVERLAPPED lpOverlapped, 
  IN DWORD           dwFlags 
);

Le paramètre CompletionRoutine est un espace réservé pour un nom de fonction fourni par le client. dwError spécifie la status d’achèvement pour l’opération qui se chevauche, comme indiqué par lpOverlapped. Le paramètre cbTransferred spécifie le nombre d’octets reçus. dwFlags contient des informations qui seraient apparues dans lpFlags si l’opération de réception s’était terminée immédiatement. Cette fonction ne retourne pas de valeur.

Les routines d’achèvement peuvent être appelées dans n’importe quel ordre, mais pas nécessairement dans l’ordre dans lequel les opérations qui se chevauchent sont effectuées. Toutefois, il est garanti que les mémoires tampons publiées soient remplies dans l’ordre dans lequel elles sont fournies.

Notes

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 .

Configuration requise

Condition requise Valeur
Client minimal pris en charge Windows 10 Build 20348
Serveur minimal pris en charge Windows 10 Build 20348
En-tête ws2spi.h

Voir aussi

WPUCloseEvent

WPUCreateEvent

WPUQueueApc

LPWSPGetOverlappedResult

LPWSPSocket