Condividi tramite


Funzione recvfrom (winsock.h)

La funzione recvfrom riceve un datagramma e archivia l'indirizzo di origine.

Sintassi

int recvfrom(
  [in]                SOCKET   s,
  [out]               char     *buf,
  [in]                int      len,
  [in]                int      flags,
  [out]               sockaddr *from,
  [in, out, optional] int      *fromlen
);

Parametri

[in] s

Descrittore che identifica un socket associato.

[out] buf

Buffer per i dati in ingresso.

[in] len

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

[in] flags

Set di opzioni che modificano il comportamento della chiamata di funzione oltre le opzioni specificate per il socket associato. Per altri dettagli, vedere le osservazioni riportate di seguito.

[out] from

Puntatore facoltativo a un buffer in una struttura sockaddr che conterrà l'indirizzo di origine al momento della restituzione.

[in, out, optional] fromlen

Puntatore facoltativo alla dimensione, in byte, del buffer a cui punta il parametro from .

Valore restituito

Se non si verifica alcun errore, recvfrom restituisce il numero di byte 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 buffer a cui punta il buf o dai parametri non si trova nello spazio indirizzi utente oppure il parametro fromlen è troppo piccolo per contenere l'indirizzo di origine dell'indirizzo peer.
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.
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 in stile flusso di byte) len era zero o negativo.
WSAEISCONN
Il socket è connesso. Questa funzione non è consentita con un socket connesso, indipendentemente dal fatto che il socket sia orientato alla connessione o senza connessione.
WSAENETRESET
Per un socket di datagramma, questo errore indica che la durata (TTL) è scaduta.
WSAENOTSOCK
Il descrittore nel parametro s 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 recuperare 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 recvfrom blocca.
WSAEMSGSIZE
Il messaggio era troppo grande per rientrare nel buffer a cui punta il parametro buf ed è stato troncato.
WSAETIMEDOUT
La connessione è stata interrotta, a causa di un errore di rete o perché il sistema sull'altra estremità è andato inattivo senza preavviso.
WSAECONNRESET
Circuito virtuale reimpostato dal lato remoto durante l'esecuzione di una chiusura definitiva o anomala. L'applicazione deve chiudere il socket; 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 recvfrom legge i dati in ingresso su socket connessi e non connessi e acquisisce l'indirizzo da cui sono stati inviati i dati. Questa funzione viene in genere usata con socket senza connessione. L'indirizzo locale del socket deve essere noto. Per le applicazioni server, questa operazione viene in genere eseguita in modo esplicito tramite binding. L'associazione esplicita è sconsigliata per le applicazioni client. Per le applicazioni client che usano questa funzione, il socket può diventare associato in modo implicito a un indirizzo locale tramite sendto, WSASendTo o WSAJoinLeaf.

Per i socket orientati ai flussi, ad esempio quelli di tipo SOCK_STREAM, una chiamata a recvfrom restituisce la quantità di informazioni attualmente disponibile, fino alle dimensioni del buffer specificato. Se il socket è stato configurato per la ricezione inline 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. I parametri from e fromlen vengono ignorati per i socket orientati alla connessione.

Per i socket orientati ai messaggi, i dati vengono estratti dal primo messaggio accodato, fino alle dimensioni del buffer specificato. Se il datagram o il messaggio è maggiore del buffer specificato, il buffer viene riempito con la prima parte del datagramma e recvfrom genera l'errore WSAEMSGSIZE. Per i protocolli non affidabili ,ad esempio UDP, i dati in eccesso andranno persi. Per UDP se il pacchetto ricevuto non contiene dati (vuoti), il valore restituito dalla funzione recvfrom è zero.

Se il parametro from è diverso da zero e il socket non è orientato alla connessione, ad esempio digitare SOCK_DGRAM), l'indirizzo di rete del peer che ha inviato i dati viene copiato nella struttura sockaddr corrispondente. Il valore a cui punta fromlen viene inizializzato alla dimensione di questa struttura e viene modificato, al ritorno, per indicare le dimensioni effettive dell'indirizzo archiviato nella struttura sockaddr .

Se nel socket non sono disponibili dati in ingresso, la funzione recvfrom blocca 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. La selezione, WSAAsyncSelect o WSAEventSelect può essere usata per determinare quando arrivano più dati.

Se il socket è orientato alla connessione e il lato remoto ha arrestato normalmente la connessione, la chiamata a recvfrom verrà completata immediatamente con zero byte ricevuti. Se la connessione è stata reimpostata , l'errore WSAECONNRESET avrà esito negativo.

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 . Quest'ultimo 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).
 
Nota Quando si esegue una chiamata Winsock bloccante, ad esempio recvfrom, 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 seguente viene illustrato l'uso della funzione recvfrom .
#ifndef UNICODE
#define UNICODE
#endif

#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")

int main()
{

    int iResult = 0;

    WSADATA wsaData;

    SOCKET RecvSocket;
    struct sockaddr_in RecvAddr;

    unsigned short Port = 27015;

    char RecvBuf[1024];
    int BufLen = 1024;

    struct sockaddr_in SenderAddr;
    int SenderAddrSize = sizeof (SenderAddr);

    //-----------------------------------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        wprintf(L"WSAStartup failed with error %d\n", iResult);
        return 1;
    }
    //-----------------------------------------------
    // Create a receiver socket to receive datagrams
    RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (RecvSocket == INVALID_SOCKET) {
        wprintf(L"socket failed with error %d\n", WSAGetLastError());
        return 1;
    }
    //-----------------------------------------------
    // Bind the socket to any address and the specified port.
    RecvAddr.sin_family = AF_INET;
    RecvAddr.sin_port = htons(Port);
    RecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    iResult = bind(RecvSocket, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr));
    if (iResult != 0) {
        wprintf(L"bind failed with error %d\n", WSAGetLastError());
        return 1;
    }
    //-----------------------------------------------
    // Call the recvfrom function to receive datagrams
    // on the bound socket.
    wprintf(L"Receiving datagrams...\n");
    iResult = recvfrom(RecvSocket,
                       RecvBuf, BufLen, 0, (SOCKADDR *) & SenderAddr, &SenderAddrSize);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
    }
 
    //-----------------------------------------------
    // Close the socket when finished receiving datagrams
    wprintf(L"Finished receiving. Closing socket.\n");
    iResult = closesocket(RecvSocket);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"closesocket failed with error %d\n", WSAGetLastError());
        return 1;
    }

    //-----------------------------------------------
    // Clean up and exit.
    wprintf(L"Exiting.\n");
    WSACleanup();
    return 0;
}


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

Requisito Valore
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

WSAEventSelect

Funzioni Winsock

Informazioni di riferimento su Winsock

Recv

send

sockaddr

socket