Réception de données via un socket datagramme
Une fois qu’une application WSK (Winsock Kernel) a lié un socket de datagramme à une adresse de transport locale, elle peut recevoir des datagrammes sur le socket. Une application WSK reçoit un datagramme sur un socket de datagramme en appelant la fonction WskReceiveFrom .
L’exemple de code suivant montre comment une application WSK peut recevoir un datagramme sur un socket de datagramme.
// 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;
}
En guise d’alternative à l’appel de la fonction WskReceiveFrom pour recevoir chaque datagramme sur un socket de datagramme, une application WSK peut activer la fonction de rappel d’événement WskReceiveFromEvent sur le socket. Si une application WSK active la fonction de rappel d’événement WskReceiveFromEvent sur un socket de datagramme, le sous-système WSK appelle la fonction de rappel d’événement WskReceiveFromEvent du socket chaque fois que de nouveaux datagrammes sont reçus sur le socket. Pour plus d’informations sur l’activation de la fonction de rappel d’événement WskReceiveFromEvent d’un socket de datagramme, consultez Activation et désactivation des fonctions de rappel d’événements.
L’exemple de code suivant montre comment une application WSK peut recevoir des datagrammes par le sous-système WSK en appelant la fonction de rappel d’événement WskReceiveFromEvent d’un socket de datagramme.
// 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;
}
}
Si la fonction de rappel d’événement WskReceiveFromEvent d’un socket de datagramme ne récupère pas tous les datagrammes de la liste des structures WSK_DATAGRAM_INDICATION pointées vers le paramètre DataIndication , elle peut conserver la liste pour un traitement ultérieur en retournant STATUS_PENDING. Dans ce cas, l’application WSK doit appeler la fonction WskRelease pour libérer la liste des structures WSK_DATAGRAM_INDICATION dans le sous-système WSK une fois qu’elle a terminé la récupération de tous les datagrammes des structures de la liste.