Compartir a través de


LPFN_WSARECVMSG función de devolución de llamada (mswsock.h)

LPFN_WSARECVMSG es un tipo de puntero de función. Implementa una función de devolución de llamada WSARecvMsg coincidente en la aplicación. El sistema usa la función de devolución de llamada para transmitirle datos en memoria o datos de archivo a través de un socket conectado.

La función de devolución de llamada WSARecvMsg recibe información de control o datos auxiliares con un mensaje, desde sockets conectados y no conectados.

Nota

Esta función es una extensión específica de Microsoft para la especificación de Windows Sockets.

Sintaxis

LPFN_WSARECVMSG LpfnWsarecvmsg;

INT LpfnWsarecvmsg(
  SOCKET s,
  LPWSAMSG lpMsg,
  LPDWORD lpdwNumberOfBytesRecvd,
  LPWSAOVERLAPPED lpOverlapped,
  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
)
{...}

Parámetros

s

Tipo: _In_ SOCKET

Descriptor que identifica el socket.

lpMsg

Tipo: _Inout_ LPWSAMSG

Puntero a una estructura WSAMSG basada en la especificación Posix.1g de la estructura msghdr.

lpdwNumberOfBytesRecvd

Tipo: _Out_opt_ LPDWORD

Puntero a un DWORD que contiene el número de bytes recibidos por esta llamada si la operación WSARecvMsg se completa inmediatamente.

Para evitar resultados potencialmente erróneos, pase NULL para este parámetro si el parámetro lpOverlapped no es NULL . Este parámetro solo puede ser NULL si el parámetro lpOverlapped no es NULL.

lpOverlapped

Tipo: _Inout_opt_ LPWSAOVERLAPPED

Puntero a una estructura WSAOVERLAPPED . Se omite en las estructuras no superpuestas.

lpCompletionRoutine

Tipo: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE

Puntero a la rutina de finalización a la que se llama cuando se completa la operación de recepción. Se omite en las estructuras no superpuestas.

Valor devuelto

Si no se produce ningún error y la operación de recepción se ha completado inmediatamente, WSARecvMsg devuelve cero. En este caso, la rutina de finalización ya se habrá programado para llamarse una vez que el subproceso de llamada esté en estado de alerta. De lo contrario, se devuelve un valor de SOCKET_ERROR y se puede recuperar un código de error específico llamando a WSAGetLastError. El código de error WSA_IO_PENDING indica que la operación superpuesta se ha iniciado correctamente y que la finalización se indicará más adelante.

Cualquier otro código de error indica que la operación no se inició correctamente y no se producirá ninguna indicación de finalización si se solicitó una operación superpuesta.

Código de error Significado
WSAECONNRESET

En el caso de un socket de datagrama UDP, este error indicaría que una operación de envío anterior dio lugar a un mensaje ICMP "Puerto inaccesible".

WSAEFAULT

El parámetro lpBuffers, lpFlags, lpFrom, lpNumberOfBytesRecvd, lpFromlen, lpOverlapped o lpCompletionRoutine no está totalmente incluido en una parte válida del espacio de direcciones del usuario: el búfer lpFrom era demasiado pequeño para acomodar la dirección del mismo nivel. Este error también se devuelve si un miembro de nombre de la estructura WSAMSG a la que apunta el parámetro lpMsg era un puntero NULL y el miembro namelen de la estructura WSAMSG no estaba establecido en cero. Este error también se devuelve si un miembro Control.buf de la estructura WSAMSG al que apunta el parámetro lpMsg era un puntero NULL y el miembro Control.len de la estructura WSAMSG no estaba establecido en cero.

WSAEINPROGRESS

Una llamada de Bloqueo de Windows Sockets 1.1 está en curso o el proveedor de servicios sigue procesando una función de devolución de llamada.

WSAEINTR

Se canceló una llamada de Bloqueo de Windows Socket 1.1 a través de WSACancelBlockingCall.

WSAEINVAL

El socket no se ha enlazado (por ejemplo, con enlace).

WSAEMSGSIZE

El mensaje era demasiado grande para caber en el búfer especificado y (solo para protocolos no confiables) se ha descartado cualquier parte final del mensaje que no cabe en el búfer.

WSAENETDOWN

Error en el subsistema de red.

WSAENETRESET

Para un socket de datagrama, este error indica que expiró el tiempo de vida.

WSAENOTCONN

El socket no está conectado (solo sockets orientados a la conexión).

WSAETIMEDOUT

Se agota el tiempo de espera del socket. Este error se devuelve si el socket tenía un tiempo de espera especificado mediante la opción de socket SO_RCVTIMEO y se superó el tiempo de espera.

WSAEOPNOTSUPP

No se admite la operación de socket. Este error se devuelve si el miembro dwFlags de la estructura WSAMSG a la que apunta el parámetro lpMsg incluye la marca de control MSG_PEEK en un socket que no es de datagrama.

WSAEWOULDBLOCK

Windows NT:

Sockets superpuestos: hay demasiadas solicitudes de E/S superpuestas pendientes. Sockets no superpuestos: el socket se marca como no desbloqueado y la operación de recepción no se puede completar inmediatamente.

WSANOTINITIALISED

Debe producirse una llamada de WSAStartup correcta antes de usar esta función.

WSA_IO_PENDING

Una operación superpuesta se inició correctamente y la finalización se indicará en un momento posterior.

WSA_OPERATION_ABORTED

La operación superpuesta se ha cancelado debido al cierre del socket.

Comentarios

La función WSARecvMsg se puede usar en lugar de las funciones WSARecv y WSARecvFrom para recibir datos y información de control opcional de sockets conectados y no conectados. La función WSARecvMsg solo se puede usar con datagramas y sockets sin formato. El descriptor de socket del parámetro s debe abrirse con el tipo de socket establecido en SOCK_DGRAM o SOCK_RAW.

Nota El puntero de función para la función WSARecvMsg se debe obtener en tiempo de ejecución realizando una llamada a la función WSAIoctl con el código de operación SIO_GET_EXTENSION_FUNCTION_POINTER especificado. El búfer de entrada pasado a la función WSAIoctl debe contener WSAID_WSARECVMSG, un identificador único global (GUID) cuyo valor identifica la función de extensión WSARecvMsg . Si se ejecuta correctamente, la salida devuela por la función WSAIoctl contiene un puntero a la función WSARecvMsg . El GUID de WSAID_WSARECVMSG se define en el archivo de encabezado Mswsock.h .

 

El miembro dwFlags de la estructura WSAMSG a la que apunta el parámetro lpMsg solo puede contener la marca de control MSG_PEEK en la entrada.

Los sockets superpuestos se crean con una llamada de función WSASocket que tiene establecida la marca WSA_FLAG_OVERLAPPED . En el caso de los sockets superpuestos, la información de recepción usa E/S superpuesta, a menos que los parámetros lpOverlapped y lpCompletionRoutine sean NULL. El socket se trata como un socket no superpuesto cuando los parámetros lpOverlapped y lpCompletionRoutine son NULL.

Se produce una indicación de finalización con sockets superpuestos. Una vez que el transporte ha consumido el búfer o los búferes, se desencadena una rutina de finalización o se establece un objeto de evento. Si la operación no se completa inmediatamente, el estado de finalización final se recupera a través de la rutina de finalización o llamando a la función WSAGetOverlappedResult .

En el caso de los sockets superpuestos, WSARecvMsg se usa para publicar uno o varios búferes en los que se colocarán los datos entrantes a medida que estén disponibles, después de lo cual se produce la indicación de finalización especificada por la aplicación (invocación de la rutina de finalización o configuración de un objeto de evento). Si la operación no se completa inmediatamente, el estado de finalización final se recupera a través de la rutina de finalización o la función WSAGetOverlappedResult .

En el caso de los sockets no superpuestos, la semántica de bloqueo es idéntica a la de la función recv estándar y los parámetros lpOverlapped y lpCompletionRoutine se omiten. Los datos que ya se hayan recibido y almacenado en búfer por el transporte se copiarán en los búferes de usuario especificados. En el caso de un socket de bloqueo sin datos recibidos y almacenados en búfer actualmente por el transporte, la llamada se bloqueará hasta que se reciban los datos. Windows Sockets 2 no define ningún mecanismo de tiempo de espera de bloqueo estándar para esta función. En el caso de los protocolos que actúan como protocolos de secuencia de bytes, la pila intenta devolver tantos datos como sea posible sujeto al espacio de búfer disponible y a la cantidad de datos recibidos disponibles. Sin embargo, la recepción de un solo byte es suficiente para desbloquear el autor de la llamada. No hay ninguna garantía de que se devuelva más de un solo byte. En el caso de los protocolos que actúan como orientados a mensajes, se requiere un mensaje completo para desbloquear al autor de la llamada.

Nota La opción de socket SO_RCVTIMEO solo se aplica a los sockets de bloqueo.

 

Los búferes se rellenan en el orden en que aparecen en la matriz a la que apunta el miembro lpBuffers de la estructura WSAMSG a la que apunta el parámetro lpMsg y los búferes se empaquetan para que no se creen agujeros.

Si esta función se completa de forma superpuesta, es responsabilidad del proveedor de servicios winsock capturar esta estructura WSABUF antes de volver de esta llamada. Esto permite a las aplicaciones compilar matrices WSABUF basadas en pila a las que apunta el miembro lpBuffers de la estructura WSAMSG a la que apunta el parámetro lpMsg .

En el caso de los sockets orientados a mensajes (un tipo de socket de SOCK_DGRAM o SOCK_RAW), un mensaje entrante se coloca en los búferes hasta el tamaño total de los búferes y la indicación de finalización se produce para sockets superpuestos. Si el mensaje es mayor que los búferes, los búferes se rellenan con la primera parte del mensaje y se pierden los datos excesivos y WSARecvMsg genera el error WSAEMSGSIZE.

Cuando la opción de socket IP_PKTINFO está habilitada en un socket IPv4 de tipo SOCK_DGRAM o SOCK_RAW, la función WSARecvMsg devuelve información de paquetes en la estructura WSAMSG a la que apunta el parámetro lpMsg . Uno de los objetos de datos de control de la estructura WSAMSG devuelta contendrá una estructura de in_pktinfo utilizada para almacenar la información de dirección de paquete recibida.

En el caso de los datagramas recibidos a través de IPv4, el miembro Control de la estructura WSAMSG recibida contendrá una estructura WSABUF que contiene una estructura WSACMSGHDR . El miembro cmsg_level de esta estructura WSACMSGHDR contendrá IPPROTO_IP, el cmsg_type miembro de esta estructura contendrá IP_PKTINFO y el miembro cmsg_data contendrá una estructura de in_pktinfo utilizada para almacenar la información de dirección de paquete IPv4 recibida. La dirección IPv4 de la estructura in_pktinfo es la dirección IPv4 desde la que se recibió el paquete.

Cuando la opción de socket IPV6_PKTINFO está habilitada en un socket IPv6 de tipo SOCK_DGRAM o SOCK_RAW, la función WSARecvMsg devuelve información de paquetes en la estructura WSAMSG a la que apunta el parámetro lpMsg . Uno de los objetos de datos de control de la estructura WSAMSG devuelta contendrá una estructura de in6_pktinfo utilizada para almacenar la información de dirección de paquete recibida.

En el caso de los datagramas recibidos a través de IPv6, el miembro Control de la estructura WSAMSG recibida contendrá una estructura WSABUF que contiene una estructura WSACMSGHDR . El miembro cmsg_level de esta estructura WSACMSGHDR contendrá IPPROTO_IPV6, el cmsg_type miembro de esta estructura contendrá IPV6_PKTINFO y el miembro cmsg_data contendrá una estructura de in6_pktinfo utilizada para almacenar la información de dirección de paquete IPv6 recibida. La dirección IPv6 de la estructura in6_pktinfo es la dirección IPv6 desde la que se recibió el paquete.

Para un socket de datagrama de doble pila, si una aplicación requiere la función WSARecvMsg para devolver información de paquetes en una estructura WSAMSG para datagramas recibidos a través de IPv4, IP_PKTINFO opción de socket debe establecerse en true en el socket. Si solo la opción de IPV6_PKTINFO está establecida en true en el socket, se proporcionará información de paquetes para datagramas recibidos a través de IPv6, pero no se puede proporcionar para datagramas recibidos a través de IPv4.

Tenga en cuenta que el archivo de encabezado Ws2ipdef.h se incluye automáticamente en Ws2tcpip.h y nunca debe usarse directamente.

Nota Todas las E/S iniciadas por un subproceso determinado se cancelan cuando se cierra ese subproceso. En el caso de los sockets superpuestos, las operaciones asincrónicas pendientes pueden producir un error si el subproceso se cierra antes de que se completen las operaciones. Para obtener más información, vea ExitThread.

 

Windows Phone 8: esta función es compatible con las aplicaciones de Windows Phone Store en Windows Phone 8 y versiones posteriores.

Windows 8.1 y Windows Server 2012 R2: esta función es compatible con las aplicaciones de la Tienda Windows en Windows 8.1, Windows Server 2012 R2 y versiones posteriores.

dwFlags

En la entrada, el miembro dwFlags de la estructura WSAMSG a la que apunta el parámetro lpMsg se puede usar para influir en el comportamiento de la invocación de función más allá de las opciones de socket especificadas para el socket asociado. Es decir, la semántica de esta función viene determinada por las opciones de socket y el miembro dwFlags de la estructura WSAMSG . El único valor de entrada posible para el miembro dwFlags de la estructura WSAMSG a la que apunta el parámetro lpMsg es MSG_PEEK.

Valor Significado
MSG_PEEK Inspecciona los datos entrantes. Los datos se copian en el búfer, pero no se quitan de la cola de entrada. Esta marca solo es válida para sockets no superpuestos.

 

Los valores posibles para el miembro dwFlags en la entrada se definen en el archivo de encabezado Winsock2.h .

En la salida, el miembro dwFlags de la estructura WSAMSG a la que apunta el parámetro lpMsg puede devolver una combinación de cualquiera de los valores siguientes.

Valor Significado
MSG_BCAST El datagrama se recibió como una difusión de capa de vínculo o con una dirección IP de destino que es una dirección de difusión.
MSG_CTRUNC Los datos de control (auxiliares) se truncaron. Había más datos de control que el espacio asignado para el proceso.
MSG_MCAST El datagrama se recibió con una dirección IP de destino que es una dirección de multidifusión.
MSG_TRUNC El datagrama se ha truncado. Había más datos que el espacio asignado para el proceso.

 

En microsoft Kit de desarrollo de software de Windows (SDK) publicado para Windows Vista y versiones posteriores, la organización de archivos de encabezado ha cambiado y los valores posibles para el miembro dwFlags en la salida se definen en el archivo de encabezado Ws2def.h que el archivo de encabezado Winsock2.h incluye automáticamente.

En las versiones del Kit de desarrollo de software de plataforma (SDK) para Windows Server 2003 y versiones anteriores, los valores posibles para el miembro dwFlags en la salida se definen en el archivo de encabezado Mswsock.h .

Nota Al emitir una llamada de Winsock de bloqueo, como WSARecvMsg con el parámetro lpOverlapped establecido en NULL, Winsock puede necesitar esperar un evento de red antes de que se pueda completar la llamada. Winsock realiza una espera alertable en esta situación, que se puede interrumpir mediante una llamada de procedimiento asincrónica (APC) programada en el mismo subproceso. La emisión de otra llamada winsock de bloqueo dentro de un APC que interrumpió una llamada de Winsock de bloqueo en curso en el mismo subproceso provocará un comportamiento indefinido y los clientes winsock nunca deben intentarlo.

 

E/S de socket superpuesta

Si una operación superpuesta se completa inmediatamente, WSARecvMsg devuelve un valor de cero y el parámetro lpNumberOfBytesRecvd se actualiza con el número de bytes recibidos y los bits de marca indicados por el parámetro lpFlags también se actualizan. Si la operación superpuesta se inicia correctamente y se completará más adelante, WSARecvMsg devuelve SOCKET_ERROR e indica el código de error WSA_IO_PENDING. En este caso, lpNumberOfBytesRecvd no se actualiza. Cuando se completa la operación superpuesta, la cantidad de datos transferidos se indica a través del parámetro cbTransferred en la rutina de finalización (si se especifica) o mediante el parámetro lpcbTransfer en WSAGetOverlappedResult. Los valores de marca se obtienen examinando el parámetro lpdwFlags de WSAGetOverlappedResult.

Se puede llamar a la función WSARecvMsg mediante E/S superpuesta desde dentro de la rutina de finalización de una función WSARecv, WSARecvFrom, WSARecvMsg, WSASend, WSASendMsg o WSASendTo . Para un socket determinado, las rutinas de finalización de E/S no se anidarán. Esto permite que las transmisiones de datos sensibles al tiempo se produzcan completamente dentro de un contexto preventivo.

El parámetro lpOverlapped debe ser válido durante la operación superpuesta. Si varias operaciones de E/S están pendientes simultáneamente, cada una debe hacer referencia a una estructura WSAOVERLAPPED independiente.

Si el parámetro lpCompletionRoutine es NULL, el parámetro hEvent de lpOverlapped se señala cuando se completa la operación superpuesta si contiene un identificador de objeto de evento válido. Una aplicación puede usar WSAWaitForMultipleEvents o WSAGetOverlappedResult para esperar o sondear en el objeto de evento.

Si lpCompletionRoutine no es NULL, el parámetro hEvent se omite y la aplicación puede usar para pasar información de contexto a la rutina de finalización. Un llamador que pasa un lpCompletionRoutine no NULL y, posteriormente, llama a WSAGetOverlappedResult para la misma solicitud de E/S superpuesta no puede establecer el parámetro fWait para esa invocación de WSAGetOverlappedResult en TRUE. En este caso, el uso del parámetro hEvent no está definido y el intento de esperar en el parámetro hEvent produciría resultados impredecibles.

La rutina de finalización sigue las mismas reglas que se estipulan para las rutinas de finalización de E/S de archivos de Windows. La rutina de finalización no se invocará hasta que el subproceso esté en un estado de espera alertable, como puede ocurrir cuando se invoca la función WSAWaitForMultipleEvents con el parámetro fAlertable establecido en TRUE .

El prototipo de la rutina de finalización es el siguiente:


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

CompletionRoutine es un marcador de posición para un nombre de función definido por la aplicación o definido por la biblioteca. El parámetro dwError especifica el estado de finalización de la operación superpuesta como se indica en el parámetro lpOverlapped . El parámetro cbTransferred especifica el número de bytes recibidos. El parámetro dwFlags contiene información que también se devuelve en el miembro dwFlags de la estructura WSAMSG a la que apunta el parámetro lpMsg si la operación de recepción se había completado inmediatamente. La función CompletionRoutine no devuelve un valor.

La devolución de esta función permite invocar otra rutina de finalización pendiente para este socket. Cuando se usa WSAWaitForMultipleEvents, se llama a todas las rutinas de finalización en espera antes de que la espera del subproceso alertable esté satisfecho con un código de retorno de WSA_IO_COMPLETION. Se puede llamar a las rutinas de finalización en cualquier orden, no necesariamente en el mismo orden en que se completan las operaciones superpuestas. Sin embargo, se garantiza que los búferes publicados se rellenen en el mismo orden en el que se especifican.

Si usa puertos de finalización de E/S, tenga en cuenta que el orden de las llamadas realizadas a WSARecvMsg es también el orden en que se rellenan los búferes. No se debe llamar a la función WSARecvMsg en el mismo socket simultáneamente desde diferentes subprocesos, ya que puede dar lugar a un orden de búfer imprevisible.

Requisitos

Requisito Value
Cliente mínimo compatible compilación 20348 de Windows 10
Servidor mínimo compatible compilación 20348 de Windows 10
Encabezado mswsock.h

Consulte también

ExitThread

IP_PKTINFO

IPV6_PKTINFO

Referencia de Winsock

Funciones Winsock

WSABUF

WSAGetLastError

WSAIoctl

WSAMSG

WSAOVERLAPPED

WSARecv

WSARecvFrom

WSASend

WSASendMsg

WSASendTo

WSAStartup

WSAWaitForMultipleEvents