Funzione di callback LPWSPRECVFROM (ws2spi.h)

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

Sintassi

LPWSPRECVFROM Lpwsprecvfrom;

int Lpwsprecvfrom(
  [in]      SOCKET s,
  [in, out] LPWSABUF lpBuffers,
  [in]      DWORD dwBufferCount,
  [out]     LPDWORD lpNumberOfBytesRecvd,
  [in, out] LPDWORD lpFlags,
  [out]     sockaddr *lpFrom,
  [in, out] LPINT lpFromlen,
  [in]      LPWSAOVERLAPPED lpOverlapped,
  [in]      LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  \[in\]    LPWSATHREADID lpThreadId,
  [in, out] LPINT lpErrno
)
{...}

Parametri

[in] s

Descrittore che identifica un socket.

[in, out] lpBuffers

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

[in] dwBufferCount

Numero di strutture WSABUF nella matrice lpBuffers .

[out] lpNumberOfBytesRecvd

Puntatore al numero di byte ricevuti da questa chiamata.

[in, out] lpFlags

Puntatore ai flag.

[out] lpFrom

Puntatore facoltativo a un buffer nella struttura sockaddr che conterrà l'indirizzo di origine al completamento dell'operazione sovrapposta.

[in, out] lpFromlen

Puntatore alla dimensione del buffer lpFrom , in byte, obbligatorio solo se è specificato lpFrom .

[in] lpOverlapped

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

[in] lpCompletionRoutine

Tipo: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE

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

\\[in\\] lpThreadId

Puntatore a una struttura WSATHREADID da usare dal provider in una chiamata successiva a WPUQueueApc. Il provider deve archiviare la struttura WSATHREADID a cui si fa riferimento (non il puntatore allo stesso) fino a quando non viene restituita la funzione WPUQueueApc .

[in, out] lpErrno

Puntatore al codice di errore.

Valore restituito

Se non si verifica alcun errore e l'operazione di ricezione è stata completata immediatamente, LPWSPRecvFrom restituisce zero. Si noti che in questo caso la routine di completamento, se specificata sarà già stata accodata. In caso contrario, viene restituito un valore di SOCKET_ERROR e in lpErrno è disponibile un codice di errore specifico. 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 non è stata avviata alcuna operazione sovrapposta e che non si verificherà alcuna indicazione di completamento.

Codice di errore Significato
WSAENETDOWN
Il sottosistema di rete non è riuscito.
WSAEFAULT
Il parametro lpFromlen non è valido: il buffer lpFrom era troppo piccolo per contenere l'indirizzo peer o lpbuffers non è completamente contenuto all'interno di una parte valida dello spazio indirizzi utente.
WSAEINTR
(Blocking) la chiamata è stata annullata tramite LPWSPCancelBlockingCall.
WSAEINPROGRESS
Il blocco della chiamata a Windows Sockets è in corso oppure il provider di servizi sta ancora elaborando una funzione di callback.
WSAEINVAL
Il socket non è stato associato (ad esempio, con LPWSPBind) o il socket non viene creato con il flag sovrapposto.
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
La connessione è stata interrotta a causa dell'attività keep-alive che rileva un errore durante l'operazione in corso.
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 eseguire LPWSPRecvFrom su un socket dopo che LPWSPShutdown è stato richiamato con come impostare su SD_RECEIVE o SD_BOTH.
WSAEWOULDBLOCK
**Windows NT:**
Socket sovrapposti: troppe richieste di I/O in sospeso in sospeso. Socket non sovrapposti: il socket è contrassegnato come non bloccante e l'operazione di ricezione non può essere completata immediatamente.
WSAEMSGSIZE
Il messaggio era troppo grande per adattarsi al buffer specificato e (solo per protocolli non affidabili) qualsiasi parte finale del messaggio che non rientra nel buffer è stata eliminata.
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 di datagram UDP questo errore indica che un'operazione di invio precedente ha generato un messaggio ICMP "Port Unreachable".
WSAEDISCON
Socket s è orientato ai messaggi e il circuito virtuale è stato normalmente chiuso dal lato remoto.
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 LPWSPRecvFrom viene usata principalmente su un socket senza connessione specificato da s Il socket non deve essere connesso. L'indirizzo locale del socket deve essere noto. Questa operazione può essere eseguita in modo esplicito tramite LPWSPBind o in modo implicito tramite LPWSPSendTo o LPWSPJoinLeaf.

Per i socket sovrapposti, questa funzione viene usata per inserire uno o più buffer in cui verranno inseriti i dati in ingresso quando diventano disponibili in un socket (possibilmente connesso), dopo il quale si verifica l'indicazione di completamento specificata dal client (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 LPWSPGetOverlappedResult. Si noti inoltre che i valori a cui punta lpFrom e lpFromlen non vengono aggiornati fino a quando non viene indicato il completamento. Le applicazioni non devono usare o disturbare questi valori fino a quando non sono stati aggiornati, pertanto il client non deve usare le variabili automatiche (ovvero basate su stack) per questi parametri.

Se sia lpOverlapped che lpCompletionRoutine sono Null, il socket in questa funzione verrà considerato come un socket non sovrapposto.

Per i socket non sovrapposti, i parametri lpOverlapped, lpCompletionRoutine e lpThreadId vengono ignorati. Tutti i dati già ricevuti e memorizzati nel buffer dal trasporto verranno copiati nei buffer utente forniti. Per il caso di un socket di blocco senza dati attualmente ricevuti e memorizzati nel buffer dal trasporto, la chiamata bloccherà finché i dati non vengono ricevuti in base alla semantica di blocco assegnata per LPWSPRecv.

I buffer forniti vengono compilati nell'ordine in cui vengono visualizzati nella matrice a cui punta lpBuffers e i buffer vengono compressi in modo che non vengano creati fori.

La matrice di strutture WSABUF a cui punta il parametro lpBuffers è temporanea. Se questa operazione viene completata in modo sovrapposto, è responsabilità del provider di servizi acquisire questa matrice di puntatori alle strutture WSABUF prima di restituire da questa chiamata. In questo modo, i client SPI Di Windows Sockets possono compilare matrici WSABUF basate su stack.

Per i tipi socket senza connessione, l'indirizzo da cui provengono i dati viene copiato nel buffer a cui punta lpFrom. In base all'input, il valore a cui punta lpFromlen viene inizializzato alla dimensione del buffer e viene modificato al completamento per indicare le dimensioni effettive dell'indirizzo archiviato.

Come indicato in precedenza per i socket sovrapposti, i parametri lpFrom e lpFromlen non vengono aggiornati fino al completamento dell'I/O sovrapposto. La memoria a cui punta questi parametri deve pertanto rimanere disponibile per il provider di servizi e non può essere allocata nel frame dello stack del client Spi Windows Sockets. I parametri lpFrom e lpFromlen vengono ignorati per i socket orientati alla connessione.

Per i socket in stile flusso di byte (ad esempio, tipo SOCK_STREAM), i dati in ingresso vengono inseriti nei buffer finché i buffer non vengono riempiti, la connessione viene chiusa o i dati memorizzati internamente nel buffer 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, un singolo messaggio in ingresso viene inserito nei buffer forniti, fino alla dimensione totale dei buffer forniti e l'indicazione di completamento si verifica per i socket sovrapposti. Se il messaggio è maggiore dei buffer forniti, i buffer vengono riempiti con la prima parte del messaggio. Se la funzionalità MSG_PARTIAL è supportata dal provider di servizi, il flag MSG_PARTIAL viene impostato in lpFlags per il socket e le successive operazioni di ricezione recupereranno il resto del messaggio. Se MSG_PARTIAL non è supportato, ma il protocollo è affidabile, LPWSPRecvFrom genera l'errore WSAEMSGSIZE e un'operazione di ricezione successiva con un buffer più grande può essere usata per recuperare l'intero messaggio. In caso contrario, il protocollo non è affidabile e non supporta MSG_PARTIAL, i dati in eccesso vengono persi e LPWSPRecvFrom genera l'errore WSAEMSGSIZE.

Il parametro lpFlags può essere usato per influenzare il comportamento della chiamata della funzione oltre le opzioni specificate per il socket associato. Ovvero, la semantica di questa funzione è determinata dalle opzioni del socket e dal parametro lpFlags . 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. Questo flag è valido solo per i socket non sovrapposti.
MSG_OOB Elabora i dati fuori banda (OOB).
MSG_PARTIAL Questo flag è solo per i socket orientati ai messaggi. Nell'output indica che i dati forniti sono una parte del messaggio trasmesso dal mittente. Le parti rimanenti del messaggio verranno fornite nelle operazioni di ricezione successive. Un'operazione di ricezione successiva con MSG_PARTIAL flag deselezionata indica la fine del messaggio del mittente. Come parametro di input, MSG_PARTIAL indica che l'operazione di ricezione deve essere completata anche se solo parte di un messaggio è stata ricevuta dal provider di servizi.

 

 

Per i socket orientati ai messaggi, il bit 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. In caso di completamento ritardato, il valore a cui punta lpFlags non viene aggiornato. Quando è stato indicato il completamento, il client SPI di Windows Sockets deve chiamare LPWSPGetOverlappedResult ed esaminare i flag a cui punta il parametro lpdwFlags .

Se un'operazione sovrapposta viene completata immediatamente, LPWSPRecv restituisce un valore zero e il parametro lpNumberOfBytesRecvd viene aggiornato con il numero di byte ricevuti e vengono aggiornati anche i bit di flag a cui punta il parametro lpFlags . Se l'operazione sovrapposta viene avviata correttamente e verrà completata in un secondo momento, LPWSPRecv 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 LPWSPGetOverlappedResult. I valori flag vengono ottenuti esaminando il parametro lpdwFlags di LPWSPGetOverlappedResult.

I provider devono consentire la chiamata di questa funzione dall'interno della routine di completamento di una funzione LPWSPRecv, LPWSPRecvFrom, LPWSPSend o LPWSPSendTo precedente. Tuttavia, per un determinato socket, le routine di completamento di I/O non possono essere 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 attesa simultaneamente, ognuna deve fare riferimento a una struttura sovrapposta separata. La struttura WSAOverlapped è definita nella relativa pagina di riferimento.

Se il parametro lpCompletionRoutine è Null, il provider di servizi segnala il membro hEvent di lpOverlapped quando l'operazione sovrapposta viene completata se contiene un handle di oggetto evento valido. Un client SPI Di Windows Sockets può usare LPWSPGetOverlappedResult per attendere o eseguire il polling sull'oggetto evento.

Se lpCompletionRoutine non è Null, il membro hEvent viene ignorato e può essere usato dal client SPI Windows Sockets per passare le informazioni di contesto alla routine di completamento. È responsabilità del provider di servizi disporre della chiamata della routine di completamento specificata dal client al termine dell'operazione sovrapposta. Poiché la routine di completamento deve essere eseguita nel contesto dello stesso thread che ha avviato l'operazione sovrapposta, non può essere richiamata direttamente dal provider di servizi. Il Ws2_32.dll offre un meccanismo APC (Procedure Call) asincrona per facilitare la chiamata delle routine di completamento.

Un provider di servizi dispone che una funzione venga eseguita nel contesto di thread e processo appropriato chiamando WPUQueueApc. Questa funzione può essere chiamata da qualsiasi contesto di processo e thread, anche da un contesto diverso dal thread e dal processo usato per avviare l'operazione sovrapposta.

WPUQueueApc accetta come parametri di input un puntatore a una struttura WSATHREADID (fornita al provider tramite il parametro di input lpThreadId ), un puntatore a una funzione APC da richiamare e un valore di contesto che viene successivamente passato alla funzione APC. Poiché è disponibile solo un singolo valore di contesto, la funzione APC stessa non può essere la routine di completamento specificata dal client. Il provider di servizi deve invece fornire un puntatore alla propria funzione APC che utilizza il valore di contesto fornito per accedere alle informazioni sul risultato necessarie per l'operazione sovrapposta e quindi richiama la routine di completamento specificata dal client.

Il prototipo per la routine di completamento fornita dal client è il seguente:

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

CompletionRoutine è un segnaposto per un nome di funzione fornito dal client. dwError specifica lo stato di completamento per l'operazione sovrapposta, come indicato da lpOverlapped. cbTransferred specifica il numero di byte ricevuti. dwFlags contiene informazioni che verrebbero visualizzate in lpFlags se l'operazione di ricezione fosse stata completata immediatamente. Questa funzione non restituisce un valore.

Le routine di completamento possono essere chiamate in qualsiasi ordine, anche se non necessariamente nello stesso ordine in cui vengono completate le operazioni sovrapposte. Tuttavia, è garantito che i buffer inviati vengano compilati nello stesso ordine in cui vengono forniti.

Nota

Tutte le operazioni di I/O avviate da un determinato thread vengono annullate quando il thread viene chiuso. Per i socket sovrapposti, le operazioni asincrone in sospeso possono avere esito negativo se il thread viene chiuso prima del completamento delle operazioni. Per altre informazioni, vedere ExitThread .

Requisiti

   
Client minimo supportato Windows 2000 Professional [solo app desktop]
Server minimo supportato Windows 2000 Server [solo app desktop]
Intestazione ws2spi.h

Vedi anche

WPUQueueApc

LPWSPGetOverlappedResult

LPWSPSocket