Condividi tramite


Funzione WSARecv (winsock2.h)

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

Sintassi

int WSAAPI WSARecv(
  [in]      SOCKET                             s,
  [in, out] LPWSABUF                           lpBuffers,
  [in]      DWORD                              dwBufferCount,
  [out]     LPDWORD                            lpNumberOfBytesRecvd,
  [in, out] LPDWORD                            lpFlags,
  [in]      LPWSAOVERLAPPED                    lpOverlapped,
  [in]      LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);

Parametri

[in] s

Descrittore che identifica un socket connesso.

[in, out] lpBuffers

Puntatore a una matrice di strutture WSABUF . Ogni struttura WSABUF contiene un puntatore a un buffer e la lunghezza, in byte, del buffer.

[in] dwBufferCount

Numero di strutture WSABUF nella matrice lpBuffers .

[out] lpNumberOfBytesRecvd

Puntatore al numero, in byte, dei dati ricevuti da questa chiamata se l'operazione di ricezione viene completata immediatamente.

Usare NULL per questo parametro se il parametro lpOverlapped non è NULL per evitare risultati potenzialmente errati. Questo parametro può essere NULL solo se il parametro lpOverlapped non è NULL.

[in, out] lpFlags

Puntatore ai flag usati per modificare il comportamento della chiamata di funzione WSARecv . Per altre informazioni, vedere la sezione Osservazioni.

[in] lpOverlapped

Puntatore a una struttura WSAOVERLAPPED (ignorata per i socket non sovrapposti).

[in] lpCompletionRoutine

Tipo: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE

Un puntatore alla routine di completamento chiamata quando l'operazione di ricezione è stata completata (ignorata per i socket non sovrapposti).

Valore restituito

Se non si verifica alcun errore e l'operazione di ricezione è stata completata immediatamente, WSARecv restituisce zero. In questo caso, la routine di completamento sarà già stata pianificata per essere chiamata una volta che il thread chiamante si trova nello stato avvisabile. In caso contrario, viene restituito un valore di SOCKET_ERROR e un codice di errore specifico può essere recuperato chiamando WSAGetLastError. Il codice di errore WSA_IO_PENDING indica che l'operazione sovrapposta è stata avviata correttamente e che il completamento verrà indicato in un secondo momento. Qualsiasi altro codice di errore indica che l'operazione sovrapposta non è stata avviata correttamente e non si verificherà alcuna indicazione di completamento.

Codice di errore Significato
WSAECONNABORTED
Circuito virtuale terminato a causa di un timeout o di un altro errore.
WSAECONNRESET
Per un socket di flusso, il circuito virtuale è stato reimpostato dal lato remoto. L'applicazione deve chiudere il socket che non è più utilizzabile. Per un socket di datagrammi UDP, questo errore indica che un'operazione di invio precedente ha generato un messaggio ICMP "Port Unreachable".
WSAEDISCON
Socket s è orientato al messaggio e il circuito virtuale è stato chiuso correttamente dal lato remoto.
WSAEFAULT
Il parametro lpBuffers non è completamente contenuto in una parte valida dello spazio degli indirizzi utente.
WSAEINPROGRESS
Una chiamata windows Sockets 1.1 bloccata è in corso oppure il provider di servizi sta ancora elaborando una funzione di callback.
WSAEINTR
La chiamata (blocco) è stata annullata dalla funzione WSACancelBlockingCall .
WSAEINVAL
Il socket non è stato associato , ad esempio con binding.
WSAEMSGSIZE
Il messaggio era troppo grande per adattarsi al buffer specificato e (solo per protocolli non affidabili) qualsiasi parte finale del messaggio che non è stata adattata al buffer è stata eliminata.
WSAENETDOWN
Il sottosistema di rete non è riuscito.
WSAENETRESET
Per un socket orientato alla connessione, questo errore indica che la connessione è stata interrotta a causa dell'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.
WSAENOTCONN
Il socket non è connesso.
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 è unidirectional e supporta solo le operazioni di invio.
WSAESHUTDOWN
Il socket è stato arrestato; non è possibile chiamare WSARecv in un socket dopo l'arresto richiamato con come impostare suSD_RECEIVE o SD_BOTH.
WSAETIMEDOUT
Connessione eliminata a causa di un errore di rete o un errore di risposta del sistema peer.
WSAEWOULDBLOCK

Windows NT: Socket sovrapposti: sono presenti troppe richieste di I/O in sospeso. Socket non sovrapposti: il socket è contrassegnato come non sbloccante e l'operazione di ricezione non può essere completata immediatamente.

WSANOTINITIALISED
Prima di usare questa funzione, è necessario eseguire una chiamata WSAStartup riuscita.
WSA_IO_PENDING
Un'operazione sovrapposta è stata avviata correttamente e il completamento verrà indicato in un secondo momento.
WSA_OPERATION_ABORTED
L'operazione sovrapposta è stata annullata a causa della chiusura del socket.

Commenti

La funzione WSARecv offre alcune funzionalità aggiuntive rispetto alla funzione recv standard in tre aree importanti:

  • Può essere usato in combinazione con socket sovrapposti per eseguire operazioni recv sovrapposte.
  • Consente di specificare più buffer di ricezione che lo rendono applicabile al tipo di I/O a dispersione/raccolta.
  • Il parametro lpFlags viene usato sia in input che restituito nell'output, consentendo alle applicazioni di percepire lo stato di output del bit del flag MSG_PARTIAL . Tuttavia, il bit MSG_PARTIAL flag non è supportato da tutti i protocolli.
La funzione WSARecv viene usata sui socket connessi o sui socket senza connessione associati specificati dal parametro s e viene usato per leggere i dati in ingresso. L'indirizzo locale del socket deve essere noto. Per le applicazioni server, questa operazione viene in genere eseguita in modo esplicito tramite l'associazione o in modo implicito tramite accettare 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 tramite connessione, WSAConnect, sendto, WSASendTo o WSAJoinLeaf.

Per i socket connessi senza connessione, questa funzione 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 sovrapposti, WSARecv viene usato per pubblicare uno o più buffer in cui i dati in ingresso verranno inseriti quando diventano disponibili, dopo il quale si verifica l'indicazione di completamento specificata dall'applicazione (chiamata della routine di completamento o dell'impostazione di un oggetto evento). Se l'operazione non viene completata immediatamente, lo stato di completamento finale viene recuperato tramite la routine di completamento o WSAGetOverlappedResult.

Nota Tutti gli I/O avviati da un determinato thread vengono annullati quando il thread viene chiuso. Per i socket sovrapposti, le operazioni asincrone in sospeso possono non riuscire se il thread viene chiuso prima del completamento delle operazioni. Per altre informazioni, vedere ExitThread .
 
Se sia lpOverlapped che lpCompletionRoutine sono NULL, il socket in questa funzione verrà considerato come socket non sovrapposto.

Per i socket non sovrapposti, la semantica di blocco è identica a quella della funzione recv standard e i parametri lpOverlapped e lpCompletionRoutine vengono ignorati. Tutti i dati già ricevuti e memorizzati nel buffer dal trasporto verranno copiati nei buffer utente specificati. Nel caso di un socket di blocco senza dati attualmente ricevuti e memorizzati nel buffer dal trasporto, la chiamata bloccherà fino alla ricezione dei dati. Windows Sockets 2 non definisce alcun meccanismo di timeout di blocco standard per questa funzione. Per i protocolli che agiscono come protocolli di byte-stream, lo stack tenta di restituire il maggior numero possibile di dati soggetti allo spazio del buffer disponibile e alla quantità di dati ricevuti disponibili. Tuttavia, la ricezione di un singolo byte è sufficiente per sbloccare il chiamante. Non vi è alcuna garanzia che verrà restituito più di un singolo byte. Per i protocolli che fungono da messaggio orientato al messaggio, è necessario sbloccare il chiamante.

Nota Le opzioni del socket SO_RCVTIMEO e SO_SNDTIMEO si applicano solo ai socket di blocco.
 
Se un protocollo agisce come flusso di byte è determinato dall'impostazione di XP1_MESSAGE_ORIENTED e XP1_PSEUDO_STREAM nella relativa struttura WSAPROTOCOL_INFO e dall'impostazione del flag di MSG_PARTIAL passato a questa funzione (per i protocolli che lo supportano). La tabella seguente elenca le combinazioni pertinenti, (un asterisco (*) indica che l'impostazione di questo bit non è importante in questo caso).
XP1_MESSAGE_ORIENTED XP1_PSEUDO_STREAM MSG_PARTIAL Agisce come
non impostato * * Flusso di byte
* Set * Flusso di byte
set Non impostato set Flusso di byte
set Non impostato non impostato Orientamento ai messaggi
 

I buffer vengono riempiti nell'ordine in cui vengono visualizzati nella matrice puntata da lpBuffers e i buffer vengono compressi in modo che non vengano creati fori.

Se questa funzione viene completata in modo sovrapposto, è responsabilità del provider di servizi Winsock acquisire le strutture WSABUF prima di restituire da questa chiamata. Ciò consente alle applicazioni di creare matrici WSABUF basate su stack puntate dal parametro lpBuffers .

Per i socket in stile flusso di byte (ad esempio, digitare SOCK_STREAM), i dati in ingresso vengono inseriti nei buffer finché non vengono riempiti i buffer, la connessione viene chiusa o i dati con buffer interno vengono esauriti. Indipendentemente dal fatto che i dati in ingresso riempiano tutti i buffer, l'indicazione di completamento si verifica per i socket sovrapposti.

Per i socket orientati ai messaggi (ad esempio, digitare SOCK_DGRAM), un messaggio in ingresso viene inserito nei buffer fino alle dimensioni totali dei buffer e l'indicazione di completamento si verifica per i socket sovrapposti. Se il messaggio è maggiore dei buffer, i buffer vengono riempiti con la prima parte del messaggio. Se la funzionalità MSG_PARTIAL è supportata dal provider di servizi sottostante, il flag di MSG_PARTIAL viene impostato in lpFlags e le operazioni di ricezione successive recuperano il resto del messaggio. Se MSG_PARTIAL non è supportato, ma il protocollo è affidabile, WSARecv genera l'errore WSAEMSGSIZE e un'operazione di ricezione successiva con un buffer più grande può essere usato per recuperare l'intero messaggio. In caso contrario, il protocollo non è attendibile e non supporta MSG_PARTIAL), i dati in eccesso vengono persi e WSARecv genera l'errore WSAEMSGSIZE.

Per i socket orientati alla connessione, WSARecv può indicare la terminazione grazia del circuito virtuale in uno dei due modi che dipendono dal fatto che il socket sia orientato al flusso di byte o al messaggio. Per i flussi di byte, zero byte che sono stati letti (come indicato da un valore restituito zero per indicare l'esito positivo e il valore lpNumberOfBytesRecvd pari a zero) indica la chiusura grazia e che non verranno mai letti più byte. Per i socket orientati ai messaggi, dove un messaggio di byte zero è spesso consentito, un errore con codice di errore di WSAEDISCON viene usato per indicare la chiusura graziata. In qualsiasi caso, si è verificato un codice di errore restituito di WSAECONNRESET .

Il parametro lpFlags può essere usato per influenzare il comportamento della chiamata alla funzione oltre le opzioni specificate per il socket associato. Vale a dire, la semantica di questa funzione è determinata dalle opzioni socket e dal parametro lpFlags . Quest'ultimo viene costruito usando l'operatore OR bit per bit con uno dei valori elencati nella tabella seguente.

Valore Significato
MSG_PEEK Visualizza i dati in ingresso. I dati vengono copiati nel buffer, ma non vengono rimossi dalla coda di input.

Questo flag è valido solo per i socket non sovrapposti.

MSG_OOB Elabora i dati OOB.
MSG_PARTIAL Questo flag è solo per socket orientati ai messaggi. Nell'output, questo flag indica che i dati specificati sono una parte del messaggio trasmesso dal mittente. Le parti rimanenti del messaggio verranno specificate nelle operazioni di ricezione successive. Un'operazione di ricezione successiva con il flag di MSG_PARTIAL deselezionata indica la fine del messaggio del mittente.

Come parametro di input, questo flag indica che l'operazione di ricezione deve essere completata anche se è stata ricevuta solo parte di un messaggio dal provider di trasporto.

MSG_PUSH_IMMEDIATE Questo flag è solo per socket orientati al flusso. Questo flag consente a un'applicazione che usa socket di flusso per indicare al provider di trasporto di non ritardare il completamento delle richieste di ricezione parzialmente riempite. Questo è un suggerimento al provider di trasporto che l'applicazione è disposta a ricevere i dati in ingresso non appena possibile senza attendere necessariamente il resto dei dati che potrebbero essere ancora in transito. Ciò che costituisce una richiesta di ricezione parzialmente compilata è una questione specifica del trasporto.

Nel caso di TCP, si riferisce al caso dei segmenti TCP in ingresso inseriti nel buffer dei dati della richiesta di ricezione in cui nessuno dei segmenti TCP indica un valore push bit pari a 1. In questo caso, TCP può contenere la richiesta di ricezione parzialmente compilata un po 'più a lungo per consentire il resto dei dati in arrivo con un segmento TCP con il bit PUSH impostato su 1. Questo flag indica a TCP di non contenere la richiesta di ricezione ma di completarla immediatamente.

L'uso di questo flag per i trasferimenti a blocchi di grandi dimensioni non è consigliato poiché l'elaborazione di blocchi parziali non è spesso ottimale. Questo flag è utile solo per i casi in cui la ricezione e l'elaborazione dei dati parziali consentono immediatamente di ridurre la latenza di elaborazione.

Questo flag è un hint anziché una garanzia effettiva.

Questo flag è supportato in Windows 8.1, Windows Server 2012 R2 e versioni successive.

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.

Tenere presente che se il provider di 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 datagram o nei socket orientati ai messaggi.

 

Per i socket orientati ai messaggi, il bit di MSG_PARTIAL viene impostato nel parametro lpFlags se viene ricevuto un messaggio parziale. Se viene ricevuto un messaggio completo, MSG_PARTIAL viene cancellato in lpFlags. Nel caso di completamento ritardato, il valore puntato da lpFlags non viene aggiornato. Quando è stato indicato il completamento, l'applicazione deve chiamare WSAGetOverlappedResult ed esaminare i flag indicati dal parametro lpdwFlags .

Nota Quando si emette una chiamata Winsock di blocco, ad esempio WSARecv con il parametro lpOverlapped impostato su NULL, Winsock potrebbe dover attendere un evento di rete prima che la chiamata possa completare. Winsock esegue un'attesa avvisabile in questa situazione, che può essere interrotta da una chiamata di routine asincrona pianificata nello stesso thread. L'emissione di un'altra chiamata winsock bloccata all'interno di un APC che ha interrotto una chiamata winsock in corso sullo stesso thread comporterà un comportamento non definito e non deve mai essere tentato dai client Winsock.
 

I/O del socket sovrapposto

Se un'operazione sovrapposta viene completata immediatamente, WSARecv restituisce un valore pari a zero e il parametro lpNumberOfBytesRecvd viene aggiornato con il numero di byte ricevuti e i bit di flag indicati dal parametro lpFlags vengono aggiornati anche. Se l'operazione sovrapposta viene avviata correttamente e verrà completata in un secondo momento, WSARecv restituisce SOCKET_ERROR e indica il codice di errore WSA_IO_PENDING. In questo caso, lpNumberOfBytesRecvd e lpFlags non vengono aggiornati. Al termine dell'operazione sovrapposta, la quantità di dati trasferiti viene indicata tramite il parametro cbTransferred nella routine di completamento (se specificato) o tramite il parametro lpcbTransfer in WSAGetOverlappedResult. I valori del flag vengono ottenuti esaminando il parametro lpdwFlags di WSAGetOverlappedResult.

La funzione WSARecv con I/O sovrapposta può essere chiamata dall'interno della routine di completamento di una funzione WSARecv precedente, WSARecvFrom, WSASend o WSASendTo. Per un determinato socket, le routine di completamento di I/O non verranno annidate. In questo modo, le trasmissioni di dati sensibili al tempo vengono eseguite interamente all'interno di un contesto preemptive.

Il parametro lpOverlapped deve essere valido per la durata dell'operazione sovrapposta. Se più operazioni di I/O sono in sospeso contemporaneamente, ognuna deve fare riferimento a una struttura WSAOVERLAPPED separata.

Se il parametro lpCompletionRoutine è NULL, il parametro hEvent di lpOverlapped viene segnalato quando l'operazione sovrapposta viene completata se contiene un handle di oggetto evento valido. Un'applicazione può usare WSAWaitForMultipleEvents o WSAGetOverlappedResult per attendere o eseguire il polling nell'oggetto evento.

Se lpCompletionRoutine non è NULL, il parametro hEvent viene ignorato e può essere usato dall'applicazione per passare le informazioni di contesto alla routine di completamento. Un chiamante che passa una richiesta non NULLlpCompletionRoutine e versioni successive chiama WSAGetOverlappedResult per la stessa richiesta di I/O sovrapposta potrebbe non impostare il parametro fWait per tale chiamata di WSAGetOverlappedResult su TRUE. In questo caso l'utilizzo del parametro hEvent non è definito e il tentativo di attendere il parametro hEvent genera risultati imprevedibili.

La routine di completamento segue le stesse regole previste per le routine di completamento di I/O file di Windows. La routine di completamento non verrà richiamata finché il thread non si trova in uno stato di attesa avvisabile, ad esempio quando viene richiamata la funzione WSAWaitForMultipleEvents con il parametro fAlertable impostato su TRUE .

Il prototipo della routine di completamento è il seguente:


void CALLBACK CompletionROUTINE(
  IN DWORD dwError, 
  IN DWORD cbTransferred, 
  IN LPWSAOVERLAPPED lpOverlapped, 
  IN DWORD dwFlags
);

CompletamentoRoutine è un segnaposto per un nome di funzione definito dall'applicazione o dalla libreria. DwError specifica lo stato di completamento per l'operazione sovrapposta, come indicato da lpOverlapped. Il parametro cbTransferred specifica il numero di byte ricevuti. Il parametro dwFlags contiene informazioni che sarebbero state visualizzate in lpFlags se l'operazione di ricezione era stata completata immediatamente. Questa funzione non restituisce un valore.

La restituzione da questa funzione consente la chiamata di un'altra routine di completamento in sospeso per questo socket. Quando si usa WSAWaitForMultipleEvents, tutte le routine di completamento in attesa vengono chiamate prima che l'attesa del thread avvisabile sia soddisfatta con un codice restituito di WSA_IO_COMPLETION. Le routine di completamento possono essere chiamate in qualsiasi ordine, non necessariamente nello stesso ordine le operazioni sovrapposte vengono completate. Tuttavia, i buffer pubblicati sono garantiti di essere compilati nello stesso ordine in cui sono specificati.

Se si usano porte di completamento di I/O, tenere presente che l'ordine delle chiamate effettuate a WSARecv è anche l'ordine in cui vengono popolati i buffer. WSARecv non deve essere chiamato nello stesso socket contemporaneamente da thread diversi, perché può causare un ordine di buffer imprevedibile.

Codice di esempio

Nell'esempio seguente viene illustrato come usare la funzione WSARecv in modalità I/O sovrapposta.
#ifndef UNICODE
#define UNICODE
#endif

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <Windows.h>

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>

// Need to link with Ws2_32.lib
#pragma comment(lib, "ws2_32.lib")

#pragma warning(disable: 4127)  // Conditional expression is a constant

#define DATA_BUFSIZE 4096

int __cdecl main(int argc, char **argv)
{
    WSADATA wsd;
    struct addrinfo *result = NULL, *ptr = NULL, hints;
    WSAOVERLAPPED RecvOverlapped;
    SOCKET ConnSocket = INVALID_SOCKET;
    WSABUF DataBuf;
    DWORD RecvBytes, Flags;
    char buffer[DATA_BUFSIZE];

    int err = 0;
    int rc;

    if (argc != 2) {
        wprintf(L"usage: %s server-name\n", argv[0]);
        return 1;
    }
    // Load Winsock
    rc = WSAStartup(MAKEWORD(2, 2), &wsd);
    if (rc != 0) {
        wprintf(L"Unable to load Winsock: %d\n", rc);
        return 1;
    }
    // Make sure the hints struct is zeroed out
    SecureZeroMemory((PVOID) & hints, sizeof (struct addrinfo));

    // Initialize the hints to retrieve the server address for IPv4
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    rc = getaddrinfo(argv[1], "27015", &hints, &result);
    if (rc != 0) {
        wprintf(L"getaddrinfo failed with error: %d\n", rc);
        return 1;
    }

    for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {

        ConnSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
        if (ConnSocket == INVALID_SOCKET) {
            wprintf(L"socket failed with error: %d\n", WSAGetLastError());
            freeaddrinfo(result);
            return 1;
        }

        rc = connect(ConnSocket, ptr->ai_addr, (int) ptr->ai_addrlen);
        if (rc == SOCKET_ERROR) {

            if (WSAECONNREFUSED == (err = WSAGetLastError())) {
                closesocket(ConnSocket);
                ConnSocket = INVALID_SOCKET;
                continue;
            }
            wprintf(L"connect failed with error: %d\n", err);
            freeaddrinfo(result);
            closesocket(ConnSocket);
            return 1;
        }
        break;
    }
    if (ConnSocket == INVALID_SOCKET) {
        wprintf(L"Unable to establish connection with the server!\n");
        freeaddrinfo(result);
        return 1;
    }

    wprintf(L"Client connected...\n");

    // Make sure the RecvOverlapped struct is zeroed out
    SecureZeroMemory((PVOID) & RecvOverlapped, sizeof (WSAOVERLAPPED));

    // Create an event handle and setup an overlapped structure.
    RecvOverlapped.hEvent = WSACreateEvent();
    if (RecvOverlapped.hEvent == NULL) {
        wprintf(L"WSACreateEvent failed: %d\n", WSAGetLastError());
        freeaddrinfo(result);
        closesocket(ConnSocket);
        return 1;
    }

    DataBuf.len = DATA_BUFSIZE;
    DataBuf.buf = buffer;

    // Call WSARecv until the peer closes the connection
    // or until an error occurs
    while (1) {

        Flags = 0;
        rc = WSARecv(ConnSocket, &DataBuf, 1, &RecvBytes, &Flags, &RecvOverlapped, NULL);
        if ((rc == SOCKET_ERROR) && (WSA_IO_PENDING != (err = WSAGetLastError()))) {
            wprintf(L"WSARecv failed with error: %d\n", err);
            break;
        }

        rc = WSAWaitForMultipleEvents(1, &RecvOverlapped.hEvent, TRUE, INFINITE, TRUE);
        if (rc == WSA_WAIT_FAILED) {
            wprintf(L"WSAWaitForMultipleEvents failed with error: %d\n", WSAGetLastError());
            break;
        }

        rc = WSAGetOverlappedResult(ConnSocket, &RecvOverlapped, &RecvBytes, FALSE, &Flags);
        if (rc == FALSE) {
            wprintf(L"WSARecv operation failed with error: %d\n", WSAGetLastError());
            break;
        }

        wprintf(L"Read %d bytes\n", RecvBytes);

        WSAResetEvent(RecvOverlapped.hEvent);

        // If 0 bytes are received, the connection was closed
        if (RecvBytes == 0)
            break;
    }

    WSACloseEvent(RecvOverlapped.hEvent);
    closesocket(ConnSocket);
    freeaddrinfo(result);

    WSACleanup();

    return 0;
}


Windows Phone 8: questa funzione è supportata per le app Windows Phone Store 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 winsock2.h
Libreria Ws2_32.lib
DLL Ws2_32.dll

Vedi anche

WSABUF

WSACloseEvent

WSACreateEvent

WSAGetOverlappedResult

WSAOVERLAPPED

WSASocket

WSAWaitForMultipleEvents

Funzioni Winsock

Informazioni di riferimento su Winsock

Recv