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 |
---|---|
Prima di usare questa funzione, è necessario che venga eseguita una chiamata WSAStartup riuscita. | |
Il sottosistema di rete non è riuscito. | |
Il parametro buf non è completamente contenuto in una parte valida dello spazio indirizzi utente. | |
Il socket non è connesso. | |
La chiamata (bloccante) è stata annullata tramite WSACancelBlockingCall. | |
È in corso una chiamata di Windows Sockets 1.1 bloccante oppure il provider di servizi sta ancora elaborando una funzione di callback. | |
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. | |
Il descrittore non è un socket. | |
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. | |
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. | |
Il socket è contrassegnato come non bloccante e l'operazione di ricezione blocca. | |
Il messaggio era troppo grande per rientrare nel buffer specificato ed è stato troncato. | |
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. | |
Circuito virtuale terminato a causa di un timeout o di un altro errore. L'applicazione deve chiudere il socket che non è più utilizzabile. | |
Connessione eliminata a causa di un errore di rete o un errore di risposta del sistema peer. | |
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:
|
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 |