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
WSANOTINITIALISED
Un appel WSAStartup réussi doit se produire avant d’utiliser cette fonction.
WSAENETDOWN
Le sous-système réseau a échoué.
WSAEFAULT
Le paramètre buf n’est pas entièrement contenu dans une partie valide de l’espace d’adressage utilisateur.
WSAENOTCONN
Le socket n'est pas connecté.
WSAEINTR
L’appel (bloquant) a été annulé via WSACancelBlockingCall.
WSAEINPROGRESS
Un appel bloquant Windows Sockets 1.1 est en cours ou le fournisseur de services traite toujours une fonction de rappel.
WSAENETRESET
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é.
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 sur un socket une fois l’arrêt appelé avec la valeur définie sur SD_RECEIVE ou SD_BOTH.
WSAEWOULDBLOCK
Le socket est marqué comme non bloquant et l’opération de réception est bloquée.
WSAEMSGSIZE
Le message était trop grand pour tenir dans la mémoire tampon spécifiée et a été tronqué.
WSAEINVAL
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.
WSAECONNABORTED
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.
WSAETIMEDOUT
La connexion a été supprimée en raison d'un échec réseau ou d'un échec de réponse du système homologue.
WSAECONNRESET
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 :
  • La mémoire tampon fournie par l’appelant est complètement pleine.
  • La connexion a été fermée.
  • La demande a été annulée ou une erreur s’est produite.
Notez que si le transport sous-jacent ne prend pas en charge MSG_WAITALL ou si le socket est en mode non bloquant, cet appel échoue avec WSAEOPNOTSUPP. En outre, si MSG_WAITALL est spécifié avec MSG_OOB, MSG_PEEK ou MSG_PARTIAL, cet appel échoue avec WSAEOPNOTSUPP. Cet indicateur n’est pas pris en charge sur les sockets de datagrammes ou les sockets orientés message.
 
Note Lors de l’émission d’un appel Winsock bloquant tel que recv, Winsock peut avoir besoin d’attendre un événement réseau avant que l’appel puisse se terminer. Winsock effectue une attente alertable dans cette situation, qui peut être interrompue par un appel de procédure asynchrone (APC) planifié sur le même thread. L’émission d’un autre appel Winsock bloquant à l’intérieur d’un APC qui a interrompu un appel Winsock bloquant en cours sur le même thread entraîne un comportement non défini et ne doit jamais être tenté par les clients Winsock.
 

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

Voir aussi

WSAAsyncSelect

WSARecv

WSARecvEx

Fonctions Winsock

Informations de référence sur Winsock

recvfrom

select

envoyer

socket