Ricezione di dati su un socket di datagrammi
Dopo che un'applicazione Winsock Kernel (WSK) ha associato un socket di datagrammi a un indirizzo di trasporto locale, può ricevere datagrammi sul socket. Un'applicazione WSK riceve un datagramma su un socket di datagrammi chiamando la funzione WskReceiveFrom .
Nell'esempio di codice seguente viene illustrato come un'applicazione WSK può ricevere un datagramma su un socket di datagrammi.
// Prototype for the receive datagram IoCompletion routine
NTSTATUS
ReceiveDatagramComplete(
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context
);
// Function to receive a datagram
NTSTATUS
ReceiveDatagram(
PWSK_SOCKET Socket,
PWSK_BUF DatagramBuffer
)
{
PWSK_PROVIDER_DATAGRAM_DISPATCH Dispatch;
PIRP Irp;
NTSTATUS Status;
// Get pointer to the provider dispatch structure
Dispatch =
(PWSK_PROVIDER_DATAGRAM_DISPATCH)(Socket->Dispatch);
// Allocate an IRP
Irp =
IoAllocateIrp(
1,
FALSE
);
// Check result
if (!Irp)
{
// Return error
return STATUS_INSUFFICIENT_RESOURCES;
}
// Set the completion routine for the IRP
IoSetCompletionRoutine(
Irp,
ReceiveDatagramComplete,
DatagramBuffer, // Use the datagram buffer for the context
TRUE,
TRUE,
TRUE
);
// Initiate the receive operation on the socket
Status =
Dispatch->WskReceiveFrom(
Socket,
DatagramBuffer,
0, // No flags are specified
NULL, // Not interested in the remote address
NULL, // Not interested in any associated control information
NULL,
NULL,
Irp
);
// Return the status of the call to WskReceiveFrom()
return Status;
}
// Receive datagram IoCompletion routine
NTSTATUS
ReceiveDatagramComplete(
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context
)
{
UNREFERENCED_PARAMETER(DeviceObject);
PWSK_BUF DataBuffer;
ULONG ByteCount;
// Check the result of the receive operation
if (Irp->IoStatus.Status == STATUS_SUCCESS)
{
// Get the pointer to the data buffer
DataBuffer = (PWSK_BUF)Context;
// Get the number of bytes received
ByteCount = (ULONG)(Irp->IoStatus.Information);
// Process the received datagram
...
}
// Error status
else
{
// Handle error
...
}
// Free the IRP
IoFreeIrp(Irp);
// Always return STATUS_MORE_PROCESSING_REQUIRED to
// terminate the completion processing of the IRP.
return STATUS_MORE_PROCESSING_REQUIRED;
}
In alternativa alla chiamata alla funzione WskReceiveFrom per ricevere ogni datagrammo su un socket di datagrammi, un'applicazione WSK può abilitare la funzione di callback dell'evento WskReceiveFromEvent sul socket. Se un'applicazione WSK abilita la funzione di callback dell'evento WskReceiveFromEvent in un socket di datagram, il sottosistema WSK chiama la funzione di callback dell'evento WskReceiveFromEvent del socket ogni volta che vengono ricevuti nuovi datagrammi sul socket. Per altre informazioni sull'abilitazione della funzione di callback dell'evento WskReceiveFromEvent di un socket di dati, vedere Abilitazione e disabilitazione delle funzioni di callback degli eventi.
L'esempio di codice seguente illustra come un'applicazione WSK può ricevere datagrammi dal sottosistema WSK chiamando la funzione di callback dell'evento WskReceiveFromEvent di un socket di dati.
// A datagram socket's WskReceiveFromEvent
// event callback function
NTSTATUS WSKAPI
WskReceiveFromEvent(
PVOID SocketContext,
ULONG Flags,
PWSK_DATAGRAM_INDICATION DataIndication
)
{
// Check for a valid data indication
if (DataIndication != NULL)
{
// Loop through the list of data indication structures
while (DataIndication != NULL)
{
// Process the data in the data indication structure
...
// Move to the next data indication structure
DataIndication = DataIndication->Next;
}
// Return status indicating the datagrams were received
return STATUS_SUCCESS;
}
// Error
else
{
// Close the socket
...
// Return success since no datagrams were indicated
return STATUS_SUCCESS;
}
}
Se la funzione di callback dell'evento WskReceiveFromEvent di un socket di datagrammi non recupera tutti gli datagrammi dall'elenco di strutture WSK_DATAGRAM_INDICATION a cui punta il parametro DataIndication , può conservare l'elenco per un'ulteriore elaborazione restituendo STATUS_PENDING. In questo caso, l'applicazione WSK deve chiamare la funzione WskRelease per rilasciare l'elenco delle strutture WSK_DATAGRAM_INDICATION al sottosistema WSK dopo aver completato il recupero di tutti gli datagrammi dalle strutture nell'elenco.