Funzione recv (winsock.h)

La funzione recv riceve i dati da un socket connesso o da un socket senza connessione associato.

Sintassi

int recv(
  [in]  SOCKET s,
  [out] char   *buf,
  [in]  int    len,
  [in]  int    flags
);

Parametri

[in] s

Descrittore che identifica un socket connesso.

[out] buf

Puntatore al buffer per ricevere i dati in ingresso.

[in] len

Lunghezza, in byte, del buffer a cui punta il parametro buf .

[in] flags

Set di flag che influisce sul comportamento di questa funzione. Vedere la sezione Note riportata di seguito. Per informazioni dettagliate sul valore possibile per questo parametro, vedere la sezione Osservazioni.

Valore restituito

Se non si verifica alcun errore, recv restituisce il numero di byte ricevuti e il buffer a cui punta il parametro buf conterrà i dati ricevuti. Se la connessione è stata chiusa normalmente, il valore restituito è zero.

In caso contrario, viene restituito un valore di SOCKET_ERROR e è possibile recuperare un codice di errore specifico chiamando WSAGetLastError.

Codice di errore Significato
WSANOTINITIALISED
Prima di usare questa funzione, è necessario che venga eseguita una chiamata WSAStartup riuscita.
WSAENETDOWN
Il sottosistema di rete non è riuscito.
WSAEFAULT
Il parametro buf non è completamente contenuto in una parte valida dello spazio indirizzi utente.
WSAENOTCONN
Il socket non è connesso.
WSAEINTR
La chiamata (bloccante) è stata annullata tramite WSACancelBlockingCall.
WSAEINPROGRESS
È in corso una chiamata di Windows Sockets 1.1 bloccante oppure il provider di servizi sta ancora elaborando una funzione di callback.
WSAENETRESET
Per un socket orientato alla connessione, questo errore indica che la connessione è stata interrotta a causa di un'attività keep-alive che ha rilevato un errore durante l'operazione in corso. Per un socket di datagramma, questo errore indica che la durata (TTL) è scaduta.
WSAENOTSOCK
Il descrittore non è un socket.
WSAEOPNOTSUPP
MSG_OOB è stato specificato, ma il socket non è in stile di flusso, ad esempio il tipo SOCK_STREAM, i dati OOB non sono supportati nel dominio di comunicazione associato a questo socket o il socket è unidirezionale e supporta solo le operazioni di invio.
WSAESHUTDOWN
Il socket è stato arrestato; non è possibile ricevere su un socket dopo che è stato richiamato l'arresto con come impostare su SD_RECEIVE o SD_BOTH.
WSAEWOULDBLOCK
Il socket è contrassegnato come non bloccante e l'operazione di ricezione blocca.
WSAEMSGSIZE
Il messaggio era troppo grande per rientrare nel buffer specificato ed è stato troncato.
WSAEINVAL
Il socket non è stato associato con binding o è stato specificato un flag sconosciuto oppure MSG_OOB è stato specificato per un socket con SO_OOBINLINE abilitato o (solo per socket di flusso di byte) len era zero o negativo.
WSAECONNABORTED
Circuito virtuale terminato a causa di un timeout o di un altro errore. L'applicazione deve chiudere il socket che non è più utilizzabile.
WSAETIMEDOUT
Connessione eliminata a causa di un errore di rete o un errore di risposta del sistema peer.
WSAECONNRESET
Circuito virtuale reimpostato dal lato remoto durante l'esecuzione di una chiusura definitiva o anomala. L'applicazione deve chiudere il socket che non è più utilizzabile. In un socket UDP-datagram, questo errore indica che un'operazione di invio precedente ha generato un messaggio ICMP "Port Unreachable".

Commenti

La funzione recv viene usata per leggere i dati in ingresso su socket orientati alla connessione o socket senza connessione. Quando si usa un protocollo orientato alla connessione, i socket devono essere connessi prima di chiamare recv. Quando si usa un protocollo senza connessione, i socket devono essere associati prima di chiamare recv.

L'indirizzo locale del socket deve essere noto. Per le applicazioni server, usare una funzione di associazione esplicita o una funzione di accettazione implicita o WSAAccept . L'associazione esplicita è sconsigliata per le applicazioni client. Per le applicazioni client, il socket può diventare associato in modo implicito a un indirizzo locale usando connect, WSAConnect, sendto, WSASendTo o WSAJoinLeaf.

Per i socket connessi o senza connessione, la funzione recv limita gli indirizzi da cui vengono accettati i messaggi ricevuti. La funzione restituisce solo messaggi dall'indirizzo remoto specificato nella connessione. I messaggi provenienti da altri indirizzi vengono eliminati in modo invisibile all'utente.

Per i socket orientati alla connessione (ad esempio, tipo SOCK_STREAM), la chiamata a recv restituirà la quantità di dati attualmente disponibile, fino alle dimensioni del buffer specificato. Se il socket è stato configurato per la ricezione in linea dei dati OOB (opzione socket SO_OOBINLINE) e i dati OOB non sono ancora letti, verranno restituiti solo i dati OOB. L'applicazione può usare il comando Ioctlsocket o WSAIoctlSIOCATMARK per determinare se devono essere letti altri dati OOB.

Per i socket senza connessione (tipo SOCK_DGRAM o altri socket orientati ai messaggi), i dati vengono estratti dal primo datagramma accodato (messaggio) dall'indirizzo di destinazione specificato dalla funzione connect .

Se il datagram o il messaggio è maggiore del buffer specificato, il buffer viene riempito con la prima parte del datagram e viene generato l'errore WSAEMSGSIZE. Per i protocolli inaffidabili (ad esempio UDP) i dati in eccesso andranno persi; per i protocolli affidabili, i dati vengono conservati dal provider di servizi fino a quando non vengono letti correttamente chiamando recv con un buffer sufficientemente grande.

Se nel socket non sono disponibili dati in ingresso, il recv chiama i blocchi e attende l'arrivo dei dati in base alle regole di blocco definite per WSARecv con il flag MSG_PARTIAL non impostato a meno che il socket non si blocchi. In questo caso, viene restituito un valore di SOCKET_ERROR con il codice di errore impostato su WSAEWOULDBLOCK. Le funzioni select, WSAAsyncSelect o WSAEventSelect possono essere usate per determinare quando arrivano più dati.

Se il socket è orientato alla connessione e il lato remoto ha arrestato correttamente la connessione e tutti i dati sono stati ricevuti, un recv verrà completato immediatamente con zero byte ricevuti. Se la connessione è stata reimpostata, un recv avrà esito negativo con l'errore WSAECONNRESET.

Il parametro flags può essere usato per influenzare il comportamento della chiamata di funzione oltre le opzioni specificate per il socket associato. La semantica di questa funzione è determinata dalle opzioni socket e dal parametro flags . Il valore possibile del parametro flags viene costruito usando l'operatore OR bit per bit con uno dei valori seguenti.

Valore Significato
MSG_PEEK Visualizza i dati in ingresso. I dati vengono copiati nel buffer, ma non vengono rimossi dalla coda di input.
MSG_OOB Elabora i dati fuori banda (OOB).
MSG_WAITALL La richiesta di ricezione verrà completata solo quando si verifica uno degli eventi seguenti:
  • Il buffer fornito dal chiamante è completamente pieno.
  • La connessione è stata chiusa.
  • La richiesta è stata annullata o si è verificato un errore.
Si noti che se il trasporto sottostante non supporta MSG_WAITALL o se il socket è in modalità non bloccante, questa chiamata avrà esito negativo con WSAEOPNOTSUPP. Inoltre, se MSG_WAITALL viene specificato insieme a MSG_OOB, MSG_PEEK o MSG_PARTIAL, questa chiamata avrà esito negativo con WSAEOPNOTSUPP. Questo flag non è supportato nei socket di datagrammi o nei socket orientati ai messaggi.
 
Nota Quando si esegue una chiamata Winsock bloccante, ad esempio recv, Winsock potrebbe dover attendere il completamento di un evento di rete. Winsock esegue un'attesa avvisabile in questa situazione, che può essere interrotta da una chiamata di procedura asincrona pianificata nello stesso thread. L'esecuzione di un'altra chiamata Winsock bloccante all'interno di un APC che ha interrotto una chiamata winsock in corso sullo stesso thread causerà un comportamento non definito e non deve mai essere tentata dai client Winsock.
 

Codice di esempio

Nell'esempio di codice seguente viene illustrato l'uso della funzione 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;
}


Codice di esempio

Per altre informazioni e un altro esempio della funzione recv, vedere Introduzione With Winsock.

Windows Phone 8: questa funzione è supportata per le app dello Store di Windows Phone in Windows Phone 8 e versioni successive.

Windows 8.1 e Windows Server 2012 R2: questa funzione è supportata per le app di Windows Store in Windows 8.1, Windows Server 2012 R2 e versioni successive.

Requisiti

   
Client minimo supportato Windows 8.1, Windows Vista [app desktop | App UWP]
Server minimo supportato Windows Server 2003 [app desktop | App UWP]
Piattaforma di destinazione Windows
Intestazione winsock.h (include Winsock2.h)
Libreria Ws2_32.lib
DLL Ws2_32.dll

Vedi anche

WSAAsyncSelect

WSARecv

WSARecvEx

Funzioni Winsock

Informazioni di riferimento su Winsock

recvfrom

select

send

Socket