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 |
---|---|
Prima di usare questa funzione, è necessario che venga eseguita una chiamata WSAStartup riuscita. | |
Il sottosistema di rete non è riuscito. | |
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. | |
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. | |
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. | |
Il socket è connesso. Questa funzione non è consentita con un socket connesso, indipendentemente dal fatto che il socket sia orientato alla connessione o senza connessione. | |
Per un socket di datagramma, questo errore indica che la durata (TTL) è scaduta. | |
Il descrittore nel parametro s 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 recuperare 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 recvfrom blocca. | |
Il messaggio era troppo grande per rientrare nel buffer a cui punta il parametro buf ed è stato troncato. | |
La connessione è stata interrotta, a causa di un errore di rete o perché il sistema sull'altra estremità è andato inattivo senza preavviso. | |
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). |
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 |