Fonction recv (winsock.h)
La fonction recv reçoit les données d’un socket connecté ou d’un socket sans connexion lié.
Syntaxe
int recv(
[in] SOCKET s,
[out] char *buf,
[in] int len,
[in] int flags
);
Paramètres
[in] s
Descripteur qui identifie un socket connecté.
[out] buf
Pointeur vers la mémoire tampon pour recevoir les données entrantes.
[in] len
Longueur, en octets, de la mémoire tampon pointée vers le paramètre buf .
[in] flags
Ensemble d’indicateurs qui influence le comportement de cette fonction. Consultez la section Notes ci-dessous. Pour plus d’informations sur la valeur possible de ce paramètre, consultez la section Remarques.
Valeur retournée
Si aucune erreur ne se produit, recv retourne le nombre d’octets reçus et la mémoire tampon pointée par le paramètre buf contiendra ces données reçues. Si la connexion a été correctement fermée, la valeur de retour est zéro.
Sinon, une valeur de SOCKET_ERROR est retournée et un code d’erreur spécifique peut être récupéré en appelant WSAGetLastError.
Code d'erreur | Signification |
---|---|
Un appel WSAStartup réussi doit se produire avant d’utiliser cette fonction. | |
Le sous-système réseau a échoué. | |
Le paramètre buf n’est pas entièrement contenu dans une partie valide de l’espace d’adressage utilisateur. | |
Le socket n'est pas connecté. | |
L’appel (bloquant) a été annulé via WSACancelBlockingCall. | |
Un appel bloquant Windows Sockets 1.1 est en cours ou le fournisseur de services traite toujours une fonction de rappel. | |
Pour un socket orienté connexion, cette erreur indique que la connexion a été interrompue en raison d’une activité de maintien en vie qui a détecté une défaillance pendant que l’opération était en cours. Pour un socket datagramme, cette erreur indique que la durée de vie (TTL, Time to Live) a expiré. | |
Le descripteur n’est pas un socket. | |
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. | |
Le socket a été arrêté ; il n’est pas possible de recevoir sur un socket une fois l’arrêt appelé avec la valeur définie sur SD_RECEIVE ou SD_BOTH. | |
Le socket est marqué comme non bloquant et l’opération de réception est bloquée. | |
Le message était trop grand pour tenir dans la mémoire tampon spécifiée et a été tronqué. | |
Le socket n’a pas été lié à bind, ou un indicateur inconnu a été spécifié, ou MSG_OOB a été spécifié pour un socket avec SO_OOBINLINE activé ou (pour les sockets de flux d’octets uniquement) len était zéro ou négatif. | |
Le circuit virtuel a été interrompu en raison d'un délai d'attente ou d'un autre échec. L’application doit fermer le socket, car il n’est plus utilisable. | |
La connexion a été supprimée en raison d'un échec réseau ou d'un échec de réponse du système homologue. | |
Le circuit virtuel a été rétabli par la partie distante exécutant une fermeture brutale ou infructueuse. L’application doit fermer le socket, car il n’est plus utilisable. Sur un socket de datagramme UDP, cette erreur indique qu’une opération d’envoi précédente a donné lieu à un message ICMP « Port inaccessible ». |
Remarques
La fonction recv est utilisée pour lire les données entrantes sur des sockets orientés connexion ou des sockets sans connexion. Lors de l’utilisation d’un protocole orienté connexion, les sockets doivent être connectés avant d’appeler recv. Lors de l’utilisation d’un protocole sans connexion, les sockets doivent être liés avant d’appeler recv.
L’adresse locale du socket doit être connue. Pour les applications serveur, utilisez une fonction de liaison explicite ou une fonction accept implicite ou WSAAccept . La liaison explicite est déconseillée pour les applications clientes. Pour les applications clientes, le socket peut devenir implicitement lié à une adresse locale à l’aide de connect, WSAConnect, sendto, WSASendTo ou WSAJoinLeaf.
Pour les sockets connectés ou sans connexion, la fonction recv 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 orientés connexion (type SOCK_STREAM par exemple), l’appel recv retourne autant de données que ce qui est actuellement disponible, jusqu’à la taille de la mémoire tampon spécifiée. Si le socket a été configuré pour la réception en ligne des données OOB (option socket SO_OOBINLINE) et que les données OOB ne sont pas encore lues, seules les données OOB sont retournées. L’application peut utiliser la commande ioctlsocket ou WSAIoctlSIOCATMARK pour déterminer si d’autres données OOB restent à lire.
Pour les sockets sans connexion (type SOCK_DGRAM ou autres sockets orientés message), les données sont extraites du premier datagramme en file d’attente (message) à partir de l’adresse de destination spécifiée par la fonction de connexion .
Si le datagramme ou le message est plus grand que la mémoire tampon spécifiée, la mémoire tampon est remplie avec la première partie du datagramme et recv génère l’erreur WSAEMSGSIZE. Pour les protocoles non fiables (par exemple, UDP), les données excédentaires sont perdues ; pour les protocoles fiables, les données sont conservées par le fournisseur de services jusqu’à ce qu’elles soient correctement lues en appelant recv avec une mémoire tampon suffisamment grande.
Si aucune donnée entrante n’est disponible au niveau du socket, l’appel recv bloque et attend que les données arrivent selon les règles de blocage définies pour WSARecv avec l’indicateur MSG_PARTIAL non défini, sauf si le socket n’est pas bloqué. Dans ce cas, une valeur de SOCKET_ERROR est retournée avec le code d’erreur défini sur WSAEWOULDBLOCK. Les fonctions select, WSAAsyncSelect ou WSAEventSelect peuvent être utilisées pour déterminer quand d’autres données arrivent.
Si le socket est orienté connexion et que le côté distant a arrêté la connexion correctement, et que toutes les données ont été reçues, une recv se termine immédiatement avec zéro octet reçu. Si la connexion a été réinitialisée, une recv échoue avec l’erreur WSAECONNRESET.
Le paramètre flags peut être utilisé pour influencer le comportement de l’appel de fonction au-delà des options spécifiées pour le socket associé. La sémantique de cette fonction est déterminée par les options de socket et le paramètre flags . La valeur possible du paramètre flags est construite à l’aide de l’opérateur OR au niveau du bit avec l’une des valeurs suivantes.
Valeur | Signification |
---|---|
MSG_PEEK | Examine les 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. |
MSG_OOB | Traite les données hors bande (OOB). |
MSG_WAITALL | La demande de réception ne se termine que lorsque l’un des événements suivants se produit :
|
Exemple de code
L’exemple de code suivant montre l’utilisation de la fonction recv .#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
int __cdecl main() {
//----------------------
// Declare and initialize variables.
WSADATA wsaData;
int iResult;
SOCKET ConnectSocket = INVALID_SOCKET;
struct sockaddr_in clientService;
char *sendbuf = "this is a test";
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
//----------------------
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != NO_ERROR) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
//----------------------
// Create a SOCKET for connecting to server
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {
printf("Error at socket(): %ld\n", WSAGetLastError() );
WSACleanup();
return 1;
}
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port of the server to be connected to.
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );
clientService.sin_port = htons( 27015 );
//----------------------
// Connect to server.
iResult = connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) );
if ( iResult == SOCKET_ERROR) {
closesocket (ConnectSocket);
printf("Unable to connect to server: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Send an initial buffer
iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
if (iResult == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 )
printf("Bytes received: %d\n", iResult);
else if ( iResult == 0 )
printf("Connection closed\n");
else
printf("recv failed: %d\n", WSAGetLastError());
} while( iResult > 0 );
// cleanup
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
Exemple de code
Pour plus d’informations et un autre exemple de la fonction recv, consultez Prise en main Avec Winsock.Windows Phone 8 : cette fonction est prise en charge pour les applications du Store Windows Phone 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
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 | winsock.h (inclure Winsock2.h) |
Bibliothèque | Ws2_32.lib |
DLL | Ws2_32.dll |