Función de devolución de llamada LPWSPSENDTO (ws2spi.h)

La función LPWSPSendTo envía datos a un destino específico mediante E/S superpuesta.

Sintaxis

LPWSPSENDTO Lpwspsendto;

int Lpwspsendto(
  [in]  SOCKET s,
  [in]  LPWSABUF lpBuffers,
  [in]  DWORD dwBufferCount,
  [out] LPDWORD lpNumberOfBytesSent,
  [in]  DWORD dwFlags,
  [in]  const sockaddr *lpTo,
  [in]  int iTolen,
  [in]  LPWSAOVERLAPPED lpOverlapped,
  [in]  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  [in]  LPWSATHREADID lpThreadId,
  [out] LPINT lpErrno
)
{...}

Parámetros

[in] s

Descriptor que identifica un socket.

[in] lpBuffers

Puntero a una matriz de estructuras WSABUF . Cada estructura WSABUF contiene un puntero a un búfer y la longitud del búfer, en bytes. En el caso de una aplicación Winsock, una vez que se llama a la función LPWSPSendTo , el sistema posee estos búferes y es posible que la aplicación no tenga acceso a ellos. Los búferes de datos a los que se hace referencia en cada estructura WSABUF son propiedad del sistema y es posible que la aplicación no tenga acceso a ellos durante la vigencia de la llamada.

[in] dwBufferCount

Número de estructuras WSABUF en la matriz lpBuffers .

[out] lpNumberOfBytesSent

Puntero al número de bytes enviados por esta llamada.

[in] dwFlags

Conjunto de marcas que especifica la forma en que se realiza la llamada.

[in] lpTo

Puntero opcional a la dirección del socket de destino en la estructura sockaddr .

[in] iTolen

Tamaño, en bytes, de la dirección a la que apunta el parámetro lpTo .

[in] lpOverlapped

Puntero a una estructura WSAOverlapped (omitida 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 ha completado la operación de envío (se omite para sockets no superpuestos).

[in] lpThreadId

Puntero a una estructura WSATHREADID que va a usar el proveedor en una llamada posterior a WPUQueueApc. El proveedor debe almacenar la estructura WSATHREADID a la que se hace referencia (no el puntero a la misma) hasta que se devuelva la función WPUQueueApc .

[out] lpErrno

Puntero al código de error.

Valor devuelto

Si no se produce ningún error y la operación de recepción se ha completado inmediatamente, LPWSPSendTo devuelve cero. Tenga en cuenta que, en este caso, la rutina de finalización, si se especifica, ya se habrá puesto en cola. De lo contrario, se devuelve un valor de SOCKET_ERROR y hay disponible un código de error específico en lpErrno. 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 no se inició ninguna operación superpuesta y no se producirá ninguna indicación de finalización.

Código de error Significado
WSAENETDOWN
Error en el subsistema de red.
WSAEACCES
La dirección solicitada es una dirección de difusión, pero no se estableció la marca adecuada.
WSAEINTR
(Bloqueo) la llamada se canceló a través de LPWSPCancelBlockingCall.
WSAEINPROGRESS
El bloqueo de la llamada a Windows Sockets está en curso o el proveedor de servicios sigue procesando una función de devolución de llamada.
WSAEFAULT
Los parámetros lpBuffers o lpTo no forman parte del espacio de direcciones del usuario o el parámetro lpTo es demasiado pequeño.
WSAENETRESET
Se ha interrumpido la conexión debido a que la actividad para mantener activa la conexión detectó un error durante la operación.
WSAENOBUFS
El proveedor de Windows Sockets notifica un interbloqueo de búfer.
WSAENOTCONN
El socket no está conectado (solo sockets orientados a la conexión).
WSAENOTSOCK
El descriptor no es un socket.
WSAEOPNOTSUPP
MSG_OOB se especificó, pero el socket no es de tipo SOCK_STREAM, los datos OOB no se admiten en el dominio de comunicación asociado a este socket, MSG_PARTIAL no se admite o el socket es unidireccional y solo admite operaciones de recepción.
WSAESHUTDOWN
Se ha apagado el socket; no es posible usar LPWSPSendTo en un socket después de invocar LPWSPShutdown con cómo se establece en SD_SEND o SD_BOTH.
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 envío no se puede completar inmediatamente.
WSAEMSGSIZE
Socket está orientado a mensajes y el mensaje es mayor que el máximo admitido por el transporte subyacente.
WSAEINVAL
El socket no se ha enlazado con LPWSPBind o el socket no se crea con la marca superpuesta.
WSAECONNABORTED
El circuito virtual finalizó debido a un tiempo de espera u otro error.
WSAECONNRESET
El circuito virtual se restableció por el lado remoto.
WSAEADDRNOTAVAIL
La dirección remota no es una dirección válida (por ejemplo, ADDR_ANY).
WSAEAFNOSUPPORT
Las direcciones de la familia especificada no se pueden usar con este socket.
WSAEDESTADDRREQ
Se requiere la dirección de destino.
WSAENETUNREACH
La red no se puede alcanzar desde este host en estos momentos.
WSA_OPERATION_ABORTED
La operación superpuesta se ha cancelado debido al cierre del socket o a la ejecución del comando SIO_FLUSH en LPWSPIoctl.

Observaciones

La función LPWSPSendTo se usa normalmente en un socket sin conexión especificado por s para enviar un datagrama contenido en uno o varios búferes a un socket del mismo nivel específico identificado por el parámetro lpTo . Incluso si el socket sin conexión se ha conectado previamente a una dirección específica con la función LPWSPConnect , lpTo invalida la dirección de destino solo para ese datagrama determinado. En un socket orientado a la conexión, se omiten los parámetros lpTo e iToLen ; en este caso, la función LPWSPSendTo es equivalente a LPWSPSend.

En el caso de los sockets superpuestos (creados con LPWSPSocket con la marca WSA_FLAG_OVERLAPPED), esto se producirá mediante E/S superpuesta, a menos que lpOverlapped y lpCompletionRoutine sean NULL en cuyo caso el socket se trata como un socket no superpuesto. Se producirá una indicación de finalización (invocación de la rutina de finalización o configuración de un objeto de evento) cuando el transporte haya consumido los búferes proporcionados. 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 LPWSPGetOverlappedResult.

En el caso de los sockets no superpuestos, los parámetros lpOverlapped, lpCompletionRoutine y lpThreadId se omiten y LPWSPSendTo adopta la semántica sincrónica normal. Los datos se copian de los búferes proporcionados 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, LPWSPSendTo devolverá solo con parte de los búferes del cliente SPI de Windows Sockets que se han consumido. Dada la misma situación de búfer y un socket de bloqueo, LPWSPSendTo se bloqueará hasta que se consuma todo el contenido del búfer del cliente SPI de Windows Sockets.

La matriz de estructuras WSABUF a las que apunta el parámetro lpBuffers es transitoria. Si esta operación se completa de forma superpuesta, es responsabilidad del proveedor de servicios capturar estas estructuras WSABUF antes de volver de esta llamada. Esto permite a las aplicaciones compilar matrices WSABUF basadas en pila.

En el caso de los sockets orientados a mensajes, se debe tener cuidado de no superar el tamaño máximo del mensaje del transporte 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.

Tenga en cuenta que la finalización correcta de un LPWSPSendTo no indica que los datos se entregaron correctamente.

El parámetro iFlags 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.

Value 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_OOB Envía datos OOB (socket de estilo de flujo, como solo SOCK_STREAM).
MSG_PARTIAL Especifica que 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 .

 

 

Si una operación superpuesta se completa inmediatamente, LPWSPSendTo 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, LPWSPSendTo devuelve SOCKET_ERROR e indica el código de error WSA_IO_PENDING. En este caso, lpNumberOfBytesSent no se actualiza. Cuando la operación superpuesta completa 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 LPWSPGetOverlappedResult.

Los proveedores deben permitir que se llame a esta función desde dentro de la rutina de finalización de una función LPWSPRecv, LPWSPRecvFrom, LPWSPSend o LPWSPSendTo . Sin embargo, para un socket determinado, las rutinas de finalización de E/S no se pueden anidar. Esto permite que las transmisiones de datos sensibles al tiempo se produzcan por completo dentro de un contexto preferente.

El parámetro lpOverlapped debe ser válido durante la operación superpuesta. Si hay varias operaciones de E/S pendientes simultáneamente, cada una debe hacer referencia a una estructura superpuesta independiente. La estructura WSAOverlapped se define en su propia página de referencia.

Si el parámetro lpCompletionRoutine es null, el proveedor de servicios señala al miembro hEvent de lpOverlapped cuando se completa la operación superpuesta si contiene un identificador de objeto de evento válido. Los clientes SPI de Windows Sockets pueden usar LPWSPGetOverlappedResult para esperar o sondear en el objeto de evento.

Si lpCompletionRoutine no es null, el miembro hEvent se omite y el cliente SPI de Windows Sockets puede usarse para pasar información de contexto a la rutina de finalización. Es posible que un cliente que pase un lpCompletionRoutine que no sea NULL y que posteriormente llame 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 miembro hEvent no está definido y al intentar esperar en el miembro hEvent se generarían resultados impredecibles.

Es responsabilidad del proveedor de servicios organizar la invocación de la rutina de finalización especificada por el cliente cuando se completa la operación superpuesta. Puesto que la rutina de finalización debe ejecutarse en el contexto del mismo subproceso que inició la operación superpuesta, no se puede invocar directamente desde el proveedor de servicios. El Ws2_32.dll ofrece un mecanismo de llamada a procedimiento asincrónico (APC) para facilitar la invocación de rutinas de finalización.

Un proveedor de servicios organiza una función que se va a ejecutar en el subproceso adecuado mediante una llamada a WPUQueueApc. Se puede llamar a esta función desde cualquier contexto de proceso y subproceso, incluso un contexto diferente del subproceso y el proceso que se usó para iniciar la operación superpuesta.

La función WPUQueueApc toma como parámetros de entrada un puntero a una estructura WSATHREADID (proporcionada al proveedor a través del parámetro de entrada lpThreadId ), un puntero a una función de APC que se va a invocar y un valor de contexto que se pasa posteriormente a la función de APC. Dado que solo hay disponible un único valor de contexto, la propia función de APC no puede ser la rutina de finalización especificada por el cliente. En su lugar, el proveedor de servicios debe proporcionar un puntero a su propia función de APC, que usa el valor de contexto proporcionado para tener acceso a la información de resultado necesaria para la operación superpuesta y, a continuación, invoca la rutina de finalización especificada por el cliente.

El prototipo de la rutina de finalización proporcionada por el cliente 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 proporcionado por el cliente. dwError especifica el estado de finalización de la operación superpuesta, como se indica en lpOverlapped. cbTransferred especifica el número de bytes enviados. No hay valores de marca definidos actualmente y el valor dwFlags será cero. Esta función no devuelve ningún valor.

Se puede llamar a las rutinas de finalización en cualquier orden, aunque no necesariamente en el mismo orden en que se completan las operaciones superpuestas. Sin embargo, el proveedor de servicios garantiza al cliente que los búferes publicados se envían en el mismo orden en que se suministran.

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 está cerrado antes de que se completen las operaciones. Consulte ExitThread para obtener más información.

Requisitos

   
Cliente mínimo compatible Windows 2000 Professional [solo aplicaciones de escritorio]
Servidor mínimo compatible Windows 2000 Server [solo aplicaciones de escritorio]
Encabezado ws2spi.h

Consulte también

WPUQueueApc

LPWSPGetOverlappedResult

LPWSPSocket