Función WSASendMsg (winsock2.h)

La función WSASendMsg envía datos e información de control opcional de 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

int WSAAPI WSASendMsg(
  [in]  SOCKET                             Handle,
  [in]  LPWSAMSG                           lpMsg,
  [in]  DWORD                              dwFlags,
  [out] LPDWORD                            lpNumberOfBytesSent,
  [in]  LPWSAOVERLAPPED                    lpOverlapped,
  [in]  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);

Parámetros

[in] Handle

Descriptor que identifica el socket.

[in] lpMsg

Estructura WSAMSG que almacena la estructura msghdr posix.1g.

[in] dwFlags

Marcas usadas para modificar el comportamiento de la llamada de función WSASendMsg . Para obtener más información, vea Uso de dwFlags en la sección Comentarios.

[out] lpNumberOfBytesSent

Puntero al número, en bytes, enviado por esta llamada si la operación de E/S se completa inmediatamente.

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

[in] lpOverlapped

Puntero a una estructura WSAOVERLAPPED . Se omite para sockets no superpuestos.

[in] 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 envío. Se omite para sockets no superpuestos.

Valor devuelto

Devuelve cero cuando se produce una finalización correcta e inmediata. Cuando se devuelve cero, se llama a la rutina de finalización especificada cuando el subproceso de llamada está en estado de alerta.

Valor devuelto de SOCKET_ERROR y llamada posterior a WSAGetLastError que devuelve WSA_IO_PENDING, indica que la operación superpuesta se ha iniciado correctamente; a continuación, la finalización se indica a través de otros medios, como a través de eventos o puertos de finalización.

Tras un error, devuelve SOCKET_ERROR y una llamada posterior a WSAGetLastError devuelve un valor distinto de WSA_IO_PENDING. En la tabla siguiente se enumeran los códigos de error.

Código de error Significado
WSAEACCES
La dirección solicitada es una dirección de difusión, pero no se ha establecido la marca adecuada.
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 lpMsg, lpNumberOfBytesSent, lpOverlapped o lpCompletionRoutine no está totalmente incluido en una parte válida del espacio de direcciones del usuario. 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 con el enlace o el socket no se creó con la marca superpuesta.
WSAEMSGSIZE
El socket está orientado a mensajes y el mensaje es mayor que el máximo admitido por el transporte subyacente.
WSAENETDOWN
Error en el subsistema de red.
WSAENETRESET
Para un socket de datagrama, este error indica que expiró el tiempo de vida.
WSAENETUNREACH
La red no es accesible.
WSAENOBUFS
El proveedor de Windows Sockets informa de un interbloqueo de búfer.
WSAENOTCONN
El socket no está conectado.
WSAENOTSOCK
El descriptor no es un socket.
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 cualquier marca de control no válida para WSASendMsg.
WSAESHUTDOWN
El socket se ha apagado; no es posible llamar a la función WSASendMsg en un socket después de que se haya invocado el apagado con el modo establecido en SD_SEND o SD_BOTH.
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_SNDTIMEO y se superó el tiempo de espera.
WSAEWOULDBLOCK
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 envío 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 o debido a la ejecución del comando SIO_FLUSH en WSAIoctl.

Comentarios

La función WSASendMsg se puede usar en lugar de las funciones WSASend y WSASendTo . La función WSASendMsg 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.

El parámetro dwFlags solo puede contener una combinación de las marcas de control siguientes: MSG_DONTROUTE, MSG_PARTIAL y MSG_OOB. El miembro dwFlags de la estructura WSAMSG a la que apunta el parámetro lpMsg se omite en la entrada y no se usa en la salida.

Nota El puntero de función para la función WSASendMsg 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_WSASENDMSG, un identificador único global (GUID) cuyo valor identifica la función de extensión WSASendMsg . Si se ejecuta correctamente, la salida devuel por la función WSAIoctl contiene un puntero a la función WSASendMsg . El GUID de WSAID_WSASENDMSG se define en el archivo de encabezado Mswsock.h .
 

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 envío usa E/S superpuesta a menos que lpOverlapped y lpCompletionRoutine sean NULL; cuando lpOverlapped y lpCompletionRoutine son NULL, el socket se trata como un socket no superpuesto. 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 no superpuestos, los parámetros lpOverlapped y lpCompletionRoutine se omiten y WSASendMsg adopta la misma semántica de bloqueo que la función de envío : los datos se copian del búfer o los búferes en el búfer del transporte. Si el socket no está desbloqueado y orientado al flujo, y no hay suficiente espacio en el búfer del transporte, WSASendMsg devuelve solo con parte de los búferes de la aplicación que se han consumido. En cambio, esta situación de búfer en un socket de bloqueo da como resultado el bloqueo de WSASendMsg hasta que se consuma todo el contenido del búfer de la aplicación.

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, se debe tener cuidado de no superar el tamaño máximo del mensaje del proveedor subyacente, que se puede obtener obteniendo el valor de la opción de socket SO_MAX_MSG_SIZE. Si los datos son demasiado largos para pasar de forma atómica a través del protocolo subyacente, se devuelve el error WSAEMSGSIZE y no se transmite ningún dato.

En un socket IPv4 de tipo SOCK_DGRAM o SOCK_RAW, una aplicación puede especificar la dirección de origen IP local que se usará para enviar con la función WSASendMsg . Uno de los objetos de datos de control pasados en la estructura WSAMSG a la función WSASendMsg puede contener una estructura de in_pktinfo utilizada para especificar la dirección de origen IPv4 local que se usará para el envío.

En un socket IPv6 de tipo SOCK_DGRAM o SOCK_RAW, una aplicación puede especificar la dirección de origen IP local que se usará para enviar con la función WSASendMsg . Uno de los objetos de datos de control pasados en la estructura WSAMSG a la función WSASendMsg puede contener una estructura de in6_pktinfo utilizada para especificar la dirección de origen IPv6 local que se usará para el envío.

Para un socket de doble pila al enviar datagramas con la función WSASendMsg y una aplicación quiere especificar una dirección de origen IP local específica que se va a usar, el método para controlar esto depende de la dirección IP de destino. Al enviar a una dirección de destino IPv4 o a una dirección de destino IPv4 asignada a IPv4, uno de los objetos de datos de control pasados en la estructura WSAMSG a la que apunta el parámetro lpMsg debe contener una estructura de in_pktinfo que contenga la dirección de origen IPv4 local que se va a usar para el envío. Cuando se envía a una dirección de destino IPv6 que no es una dirección IPv4 asignada a IPv6, uno de los objetos de datos de control pasados en la estructura WSAMSG a la que apunta el parámetro lpMsg debe contener una estructura de in6_pktinfo que contenga la dirección de origen IPv6 local que se va a usar para el envío.

Nota La opción de socket SO_SNDTIMEO solo se aplica a los sockets de bloqueo.
 
Nota La finalización correcta de un WSASendMsg no indica que los datos se entregaron correctamente.
 
Nota Al emitir una llamada de Winsock de bloqueo como WSASendMsg con el parámetro lpOverlapped establecido en NULL, Winsock puede necesitar esperar a 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.
 

dwFlags

El parámetro de entrada dwFlags se puede usar para influir en el comportamiento de la invocación de función más allá de las opciones especificadas para el socket asociado. Es decir, la semántica de esta función viene determinada por las opciones de socket y el parámetro dwFlags . Este último se construye mediante el operador OR bit a bit con cualquiera de los valores siguientes.
Valor Significado
MSG_DONTROUTE Especifica que los datos no deben estar sujetos a enrutamiento. Un proveedor de servicios de Windows Sockets puede optar por omitir esta marca.
MSG_PARTIAL Especifica que lpMsg-lpBuffers> solo contiene un mensaje parcial. Tenga en cuenta que los transportes que no admiten transmisiones de mensajes parciales devolverán el código de error WSAEOPNOTSUPP .
 

Los valores posibles para el parámetro dwFlags se definen en el archivo de encabezado Winsock2.h .

En la salida, no se usa el miembro dwFlags de la estructura WSAMSG a la que apunta el parámetro lpMsg .

E/S de socket superpuesta

Si una operación superpuesta se completa inmediatamente, WSASendMsg devuelve un valor de cero y el parámetro lpNumberOfBytesSent se actualiza con el número de bytes enviados. Si la operación superpuesta se inicia correctamente y se completará más adelante, WSASendMsg devuelve SOCKET_ERROR e indica el código de error WSA_IO_PENDING. En este caso, lpNumberOfBytesSent 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.
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. Consulte ExitThread para obtener más información.
 

Se puede llamar a la función WSASendMsg mediante E/S superpuesta desde dentro de la rutina de finalización de una función anterior, WSARecvFrom, WSARecvFrom, LPFN_WSARECVMSG (WSARecvMsg),WSASend, WSASendMsg o WSASendTo . 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 e intentar 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, por ejemplo, con WSAWaitForMultipleEvents llamado con el parámetro fAlertable establecido en TRUE.

Los proveedores de transporte permiten que una aplicación invoque las operaciones de envío y recepción desde dentro del contexto de la rutina de finalización de E/S del socket y garantice que, 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 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
);

La función 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 indica el número de bytes enviados. Actualmente no hay ningún valor de marca definido y el parámetro dwFlags será cero. La función CompletionRoutine no devuelve un valor.

La devolución de esta función permite invocar otra rutina de finalización pendiente para el socket. 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 envían en el mismo orden en que se especifican.

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.

Requisitos

Requisito Value
Cliente mínimo compatible Windows 8.1, Windows Vista [aplicaciones de escritorio | Aplicaciones para UWP]
Servidor mínimo compatible Windows Server 2008 [aplicaciones de escritorio | aplicaciones para UWP]
Plataforma de destino Windows
Encabezado winsock2.h (incluya Mswsock.h)
Library Ws2_32.lib
Archivo DLL Ws2_32.dll

Consulte también

ExitThread

IPV6_PKTINFO

IP_PKTINFO

WSABUF

WSACancelBlockingCall

WSAGetLastError

WSAGetOverlappedResult

WSAIoctl

WSAMSG

WSAOVERLAPPED

WSASend

WSASendTo

WSASocket

WSAStartup

WSAWaitForMultipleEvents

Funciones winsock

Referencia de Winsock

bind

in6_pktinfo

in_pktinfo

enviar

shutdown